📄 en_sock.c
字号:
/*
** Initialize network storage
*/
en_cd_InitTargetData( );
#if EN_MAX_OUTGOING_CONNECTIONS
sSeed.pRoutine = ( OE_pTaskFuncType ) en_cd_MngOutgoingEncapTask;
sSeed.pParameter = NULL;
sSeed.pStack = NULL;
sSeed.iStackSize = EP_MNG_OUTGOING_STACK_SIZE;
sSeed.nPrio = ENCAP_MNG_TASK_PRIO;
sSeed.pTaskName = "ENCAPMng";
lTaskID = GS_NewTask( &sSeed );
#endif
sSeed.pRoutine = ( OE_pTaskFuncType ) en_cd_UDPRecvTask;
sSeed.pParameter = NULL;
sSeed.pStack = NULL;
sSeed.iStackSize = EN_SOCKET_STACK_SIZE;
sSeed.nPrio = UDP_RECV_TASK_PRIO;
sSeed.pTaskName = "IRUDP";
lTaskID = GS_NewTask( &sSeed );
sSeed.pRoutine = ( OE_pTaskFuncType ) en_cd_Class1RecvTask;
sSeed.pParameter = NULL;
sSeed.pStack = NULL;
sSeed.iStackSize = EN_SOCKET_STACK_SIZE;
sSeed.nPrio = CLASS1_RECV_TASK_PRIO;
sSeed.pTaskName = "IRCLASS1";
lTaskID = GS_NewTask( &sSeed );
lSockFd = en_cd_PostListen( );
for ( ;; )
{
UC_SetMem( ( char * ) &sCli_addr, 0, sizeof( sCli_addr ) );
sCli_addr.sin_family = AF_INET;
sCli_addr.sin_addr.s_addr = htonl( INADDR_ANY ); /* accept from anybody */
sCli_addr.sin_port = htons( 0 );
lAddrLen = sizeof( sCli_addr );
/*
** Wait for a connect request from the client
*/
#if defined( WIN32 )
nt_Suspend( );
#endif
lSockFd2 = accept( lSockFd, ( struct sockaddr * ) & sCli_addr, &lAddrLen );
#if defined( WIN32 )
nt_Resume( );
#endif
if ( lSockFd2 == OE_ERROR )
{
/*
** Perhaps it is just temporary, log the problem, wait to allow us to
** catch our breadth and then continue
*/
GS_LogEvent( EN_ACCEPT_ERR, OE_SOCKET_ERRNO,
0,
WARNING );
OE_TaskDelay( MSEC2TICKS(1000) ); /* One second */
continue;
}
/*
** make sure we are within the limits for the number of simultaneous sockets
*/
if ((EN_MAX_INCOMING_CONNECTIONS <= lECE_connects_in) ||
(MAX_TCP_SOCKETS <= lECE_connects))
{
closesocket(lSockFd2); /* Close the socket right away, we are up to our limit */
OE_TaskDelay( MSEC2TICKS(1000) ); /* Delay for 1 second maybe room will become available */
continue; /* return to the forever loop */
}
/*
** Somebody wants to connect to us, give them a server
** Create a task to process the request from the client.
** Go ahead and wait for further requests
*/
psEce = GS_Malloc( sizeof( ECE ) ); /* Allocate the endopoint structure */
UC_SetMem( psEce, 0, sizeof( ECE ) ); /* Zero out all fields */
psEce->lSockFd = lSockFd2;
psEce->sEid.u.type = ECE_TYPE_INBOUND; /* Assign an inbound connection id */
psEce->lState = ECE_STATE_CONNECTED; /* We are connected */
psEce->sEid.u.idx = lSockFd2; /* Form the handle, idx is socket # */
psEce->sEid.u.seq = lTotal_lECE_connects; /* Add in the Total # of connections */
#ifndef _WIN32
psEce->sAddr.sin_len = sizeof( struct sockaddr_in );
#endif
lAddrLen = sizeof psEce->sAddr;
#if defined( WIN32 )
nt_Suspend( );
#endif
nStatus = getpeername( lSockFd2, ( struct sockaddr * ) & psEce->sAddr, ( INT32 * ) & lAddrLen );
#if defined( WIN32 )
nt_Resume( );
#endif
if ( nStatus == OE_ERROR )
{
/*
** Couldn't get the peername we are connected to
*/
GS_LogEvent( EN_UNKNOWN_HOST,
OE_SOCKET_ERRNO,
0,
TRIVIAL );
}
/*
** We need to create the message queue so we can pass it to
** the send task
*/
sSendTaskMsgQueue = OE_MsgQCreate( 100, /* Number of messages, */
sizeof( EnCdMessageType ),
MSG_Q_PRIORITY );
/*
** Could not create the send queue for the send/recv pair. Log it but
** warn only. There may be other connections still active and fully
** functional
*/
if ( sSendTaskMsgQueue == 0 )
{
/*
** Close the socket. Queue creation failed, no use going on
*/
GS_LogEvent( EN_QUEUE_CR_ERR,
OE_SOCKET_ERRNO,
0,
WARNING );
closesocket( lSockFd2 );
continue;
}
psEce->sOutputQ = sSendTaskMsgQueue;
sprintf( achTaskName, "IR%x", sCli_addr.sin_addr.s_addr );
/*
** The receive task will have the lowest priority of all the socket level tasks.
** This is to keep the system from bogging down if it is overwhelemed with
** packets from outside clients
*/
sSeed.pRoutine = ( OE_pTaskFuncType ) en_cd_EncapRecvTask;
sSeed.pParameter = ( void * ) psEce;
sSeed.pStack = NULL;
sSeed.iStackSize = EN_SOCKET_STACK_SIZE;
sSeed.nPrio = IN_RECV_TASK_PRIO;
sSeed.pTaskName = achTaskName;
/*
** The following create call uses the OE_CreateTask call because it can be deleted. As of this
** writting there is no GS_DeleteTask routine in the GS_Utils library
*/
lTaskID = OE_CreateTask( &sSeed );
if ( lTaskID == 0 )
{
/*
** We could not spawn the task for the inclomming connection request.
** We may already have fully functional connections and this is
** exceeding a quota of some type. Warn here, let the other
** connections continue operating.
*/
GS_LogEvent( EN_TASK_SP_ERR,
OE_SOCKET_ERRNO,
0,
WARNING );
closesocket( lSockFd2 );
continue;
}
} /* End forever */
} /* end en_cd_PassiveWaitTask( ) */
/*---------------------------------------------------------------------------
** en_cd_TcpConnect( )
**---------------------------------------------------------------------------
*/
UINT32 en_cd_TcpConnect( struct sockaddr_in * psF_Addr,
UINT32 * lSockfd,
UINT32 * nErr )
{
UINT32 lNewSockFd;
INT32 nStatus = 0;
UINT32 nHaveFd = OE_ERROR;
UINT32 lOptSet = 1;
struct sockaddr_in sCli_addr;
UINT32 lSize;
do
{
/*
** create a socket to use for outgoing connections
*/
if ( ( lNewSockFd = socket( AF_INET, SOCK_STREAM, 0 ) ) == OE_ERROR )
{
nStatus = lNewSockFd;
break;
}
nHaveFd = OK;
/*
** set common socket options. Should not get any errors at
** this point, but check for them anyway.
*/
lSize = 16384;
if ( ( nStatus = setsockopt( lNewSockFd,
SOL_SOCKET,
SO_SNDBUF,
( char * ) &lSize,
sizeof( lSize ) ) ) == OE_ERROR )
break;
lSize = 16384;
if ( ( nStatus = setsockopt( lNewSockFd,
SOL_SOCKET,
SO_RCVBUF,
( char * ) &lSize,
sizeof( lSize ) ) ) == OE_ERROR )
break;
if ( ( nStatus = setsockopt( lNewSockFd,
SOL_SOCKET,
SO_KEEPALIVE,
( char * ) &lOptSet,
sizeof( lOptSet ) ) ) == OE_ERROR )
break;
if ( ( nStatus = setsockopt( lNewSockFd,
IPPROTO_TCP,
TCP_NODELAY,
( char * ) &lOptSet,
sizeof( lOptSet ) ) ) == OE_ERROR )
UC_SetMem( ( char * ) &sCli_addr, 0, sizeof( sCli_addr ) );
sCli_addr.sin_family = AF_INET;
sCli_addr.sin_port = htons( 0 );
sCli_addr.sin_addr.s_addr = htonl( INADDR_ANY );
if ( bind( lNewSockFd, ( struct sockaddr * ) & sCli_addr, sizeof( sCli_addr ) ) == OE_ERROR ){
DBLN( "bind()==OE_ERROR" );
break;
}
/*
** Initiate a connection to the host
*/
#if defined( WIN32 )
nt_Suspend( );
#endif
nStatus = connect( lNewSockFd, ( struct sockaddr * ) psF_Addr, sizeof( *psF_Addr ) );
#if defined( WIN32 )
nt_Resume( );
#endif
if( nStatus == OE_ERROR )
{
/*
** Something happened. Could be that the host we were going to
** connect to shut down. This should not be a fatal error as it might
** not be our fault
*/
GS_LogEvent( EN_CONNECT_ERR,
OE_SOCKET_ERRNO,
0,
WARNING );
break;
}
} while ( 0 );
if ( nStatus == OE_ERROR )
{
if ( nHaveFd == OK )
closesocket( lNewSockFd );
*nErr = OE_SOCKET_ERRNO;
return ( OE_ERROR );
}
else
{
*lSockfd = lNewSockFd;
return ( OK );
}
} /* end en_cd_TcpConnect( ) */
/*---------------------------------------------------------------------------
** en_cd_UDPSend( )
**---------------------------------------------------------------------------
*/
UINT32 en_cd_UDPSend( UINT32 fd,
SOCK_WDESC * psWriteDesc,
UINT32 flags,
struct sockaddr_in * to,
UINT32 * pnErr )
{
struct msghdr psWriteMsg;
INT32 nBytes;
UC_SetMem( ( caddr_t ) &psWriteMsg, 0, sizeof( psWriteMsg ) );
psWriteMsg.msg_iov = psWriteDesc->psW_iov;
psWriteMsg.msg_iovlen = psWriteDesc->lW_iovlen;
if ( to )
{
psWriteMsg.msg_name = ( caddr_t ) to;
psWriteMsg.msg_namelen = sizeof( *to );
}
if ( ( nBytes = sendmsg( fd, &psWriteMsg, flags ) ) == OE_ERROR )
{
*pnErr = nBytes; /* !!! !!! !!! nBytes is always OE_ERROR */
return ( OE_ERROR );
}
else
{
return ( OK );
}
} /* end en_cd_UDPSend( ) */
/*---------------------------------------------------------------------------
** en_cd_UDPEncapSendTask( )
**---------------------------------------------------------------------------
*/
TASKRETURN en_cd_UDPEncapSendTask( TASKPARAM )
{
EnCdMessageType EnCdMessage;
UINT32 nShutdown = FALSE;
OE_Q_ID sSendTaskMsgQueue;
UINT32 lSid = 0;
UINT32 lSockFd;
UINT32 nStatus;
SOCK_WDESC sWriteDesc;
lSockFd = sUDPEce.lSockFd;
sSendTaskMsgQueue = sUDPEce.sOutputQ;
while ( 1 )
{
nStatus = OE_MsgQReceive( sSendTaskMsgQueue, /* Queue to wait at */
( char * ) &EnCdMessage,
sizeof EnCdMessage, /* Size */
WAIT_FOREVER ); /* Wait forever */
switch ( EnCdMessage.Command )
{
/*
** Encap Message to send. SENDCOMMBUF same but at end we need to
** dipose of combuffer
*/
case SENDINCORPMESSAGE:
case SENDCOMMBUF:
if ( EnCdMessage.PacketBuf != NULL )
{
/*
** Form the iov's for sendmessage
*/
en_cd_FormatIOV( EnCdMessage.PacketBuf, &sWriteDesc );
/*
** Write to the socket. Check for a possible
** error. Close down the connection if the
** error is not one of the flow control
** errors.
**
** Packets are sent in there entirety, no need to loop until
** complete message sent
*/
if ( en_cd_UDPSend( lSockFd, &sWriteDesc, 0, &EnCdMessage.PacketBuf->sEce.sAddr, &nStatus ) == OE_ERROR )
{
if ( ( nStatus != EWOULDBLOCK ) && ( nStatus != ENOBUFS ) )
{
/* Nothing we can do about errors, ignore them */
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -