⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 en_sock.c

📁 基于EthernetIP协议的应用程序,可以读取AB公司Controllogix系列Ethernetip协议PLC数据. 此软件代码可用于工业控制.
💻 C
📖 第 1 页 / 共 5 页
字号:
      GS_DeleteTask( 0 );
   }

   for ( iConnIndex = 0;
         iConnIndex < ( sizeof( sMulticastTbl ) / sizeof( sMulticastTbl[ 0 ] ) );
         iConnIndex++ )
   {
      sMulticastTbl[ iConnIndex ].iSocket = lSockFd;
   } /* End for connections in sMulticastTbl */
#endif
   /*
   ** Assign an inbound connection id. Form the handle, idx is socket #
   ** Add in the lTotal number of connections
   */

   sClass1Ece.sEid.u.type = ECE_TYPE_INBOUND;
   sClass1Ece.lState = ECE_STATE_CONNECTED;
   sClass1Ece.sEid.u.idx = lSockFd;
   sClass1Ece.sEid.u.seq = lTotal_lECE_connects;
#ifndef _WIN32
	   sClass1Ece.sAddr.sin_len = sizeof( struct sockaddr_in );
#endif
   /*
   ** Mark as UDP connection. lSockFd used primarily by the Start Class 1
   ** function to enable multicast reception
   */

   sClass1Ece.lFlags = ECE_FLAG_NOSESSION;
   sClass1Ece.lSockFd = lSockFd;

      psPacketBuf = PktBufAlloc( );    /* Allocate message dynamically */
      if ( psPacketBuf == NULL )
      {
         GS_LogEvent( EN_RESOURCE,
                     0,
                     0,
                     FATAL );
      }
   while ( 1 )
   {
#if defined( WIN32 )
      nt_Suspend( );
#endif
      lBytesReceived = recvfrom(lSockFd,
                                ( char * ) psPacketBuf->abData,
                                PKTBUF_MAX_DATA,
                                0,
                                ( struct sockaddr * ) & sClientAddr,
                                &lSockAddrSize );
#if defined( WIN32 )
      nt_Resume( );
#endif
      psPacketBuf->pData = &psPacketBuf->abData;
      psMsg = ( CPFHDR * ) psPacketBuf->pData;

      if (( lBytesReceived == 0 ) || ( lBytesReceived == OE_ERROR ))
      {
         continue;
      }

      psPacketBuf->sEce.sAddr = sClientAddr;
      psMsg->iAs_type = ENCAP_TO_HS( psMsg->iAs_type );
      psMsg->iAs_length = ENCAP_TO_HS( psMsg->iAs_length );
      psPacketBuf->lLength = lBytesReceived;

      /*
      ** Parse the encapsulated Class1 packet
      */
      en_cd_ParseClass1Packet( psPacketBuf );

   }  /* End forever */

}  /* en_cd_Class1RecvTask */


/*---------------------------------------------------------------------------
** en_cd_UDPRecvTask( )
**---------------------------------------------------------------------------
*/

TASKRETURN en_cd_UDPRecvTask( TASKPARAM )
{
   UINT32          lBytesReceived;
   struct sockaddr_in sClientAddr;
   ENCAPH          *psEncapHdr;
   PKTBUF          *psPacketBuf;
   UINT32          lSockAddrSize;
   UINT32          lSockFd;
   UINT32          lSendTaskId;
   GS_TaskSeedType sSeed;
   OE_Q_ID            sSendTaskMsgQueue;
   UINT32          nSendTaskPriority;
   struct sockaddr_in sSrvrAddr;


   lSockAddrSize = sizeof( struct sockaddr_in );
   UC_SetMem( ( char * ) &sSrvrAddr, 0, sizeof( sSrvrAddr ) );
#ifndef _WIN32
	   sSrvrAddr.sin_len = ( UINT8 ) lSockAddrSize;
#endif
   sSrvrAddr.sin_family = AF_INET;
   sSrvrAddr.sin_addr.s_addr = htonl( INADDR_ANY );
   sSrvrAddr.sin_port = htons( lEncapServerPort );

   if ( ( lSockFd = socket( AF_INET, SOCK_DGRAM, 0 ) ) == OE_ERROR )
   {
      /*
      ** Need a socket to do anything, so fatal out
      */

      GS_LogEvent( EN_SOCKET_ERR,
                   OE_SOCKET_ERRNO,
                   0,
                   FATAL );
      GS_DeleteTask( 0 );
   }

   /*
   **	Bind the server to PORT, which the client knows
   */

   if ( bind( lSockFd, ( struct sockaddr * ) & sSrvrAddr, sizeof( sSrvrAddr ) ) == OE_ERROR )
   {
      /*
      ** If we can't bind, no one can conect, fatal out
      */

      GS_LogEvent( EN_BIND_ERR,
                  OE_SOCKET_ERRNO,
                  0,
                  FATAL );
      GS_DeleteTask( 0 );
   }

   /*
   ** Assign an inbound connection id. Form the handle, idx is socket #
   ** Add in the lTotal number of connections
   */

   UC_SetMem( &sUDPEce, 0, sizeof sUDPEce );
   sUDPEce.sEid.u.type = ECE_TYPE_INBOUND;
   sUDPEce.lState = ECE_STATE_CONNECTED;
   sUDPEce.sEid.u.idx = lSockFd;
   sUDPEce.sEid.u.seq = lTotal_lECE_connects;
#ifndef _WIN32
	   sUDPEce.sAddr.sin_len = sizeof( struct sockaddr_in );
#endif
   sUDPEce.lFlags = ECE_FLAG_NOSESSION;  /* Mark as UDP connection */
   sUDPEce.lSockFd = lSockFd;

   /*
   ** 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 );

   /*
   ** This is FATAL we are in the beginning of the ball game and we are already
   ** having problems creating message queues. Further, this is a critical
   ** queue
   **/

   GS_LogEventIf( ( sSendTaskMsgQueue == 0 ),
                   EN_QUEUE_CR_ERR,
                   OE_SOCKET_ERRNO,
                   0,
                   FATAL );

   sUDPEce.sOutputQ = sSendTaskMsgQueue;
   nSendTaskPriority = UDP_SEND_TASK_PRIO;

   sSeed.pRoutine = ( OE_pTaskFuncType ) en_cd_UDPEncapSendTask;
   sSeed.pParameter = NULL;
   sSeed.pStack = NULL;
   sSeed.iStackSize = EN_SOCKET_STACK_SIZE;
   sSeed.nPrio = nSendTaskPriority;
   sSeed.pTaskName = "ISUDP";
   lSendTaskId = GS_NewTask( &sSeed );

   /*
   ** This is FATAL we are in the beginning of the ball game and we are already
   ** having problems creating tasks.  And the DP send task is critical to the
   ** operation.
   */

   GS_LogEventIf( ( lSendTaskId == 0 ),
                 EN_TASK_SP_ERR,
                 OE_SOCKET_ERRNO,
                 0,
                 FATAL );
   sUDPEce.lSendTaskID = lSendTaskId;

   while ( 1 )
   {
      psPacketBuf = PktBufAlloc( );    /* Allocate message dynamically */
      if ( psPacketBuf == NULL )
      {
         GS_LogEvent( EN_RESOURCE,
                     0,
                     0,
                     WARNING );
         OE_TaskDelay( MSEC2TICKS(1000)  );           /* Delay for a second, maybe memory will
                                        * be freed up */
         continue;                     /* Back to the beginning of the while
                                        * loop */
      }
      psEncapHdr = &psPacketBuf->sEncap.sHdr;
      psPacketBuf->sOutputQ = sSendTaskMsgQueue;
#if defined( WIN32 )
      nt_Suspend( );
#endif
      lBytesReceived = recvfrom( lSockFd,
                                ( char * ) psEncapHdr,
                                PKTBUF_MAX_DATA,
                                0,
                                ( struct sockaddr * ) & sClientAddr,
                                &lSockAddrSize );

#if defined( WIN32 )
      nt_Resume( );
#endif

      /*
      ** Probably trouble. Getting off the recv call told old us the socket was
      ** ready to read, but actually read gives us 0 bytes. Probably shut down
      ** at the other end.  We will shut down here too.
      */

      if (( lBytesReceived == 0 ) || ( lBytesReceived == OE_ERROR ))
      {
         PktBufFree( psPacketBuf );      /* Free the buffer */
         continue;
      }
      psPacketBuf->sEce.sAddr = sClientAddr;

      /*
      ** Swap the byte ordering
      */

      psEncapHdr->iEncaph_length  = ENCAP_VALUE_SHORT( psEncapHdr->iEncaph_length );
      psEncapHdr->iEncaph_command = ENCAP_VALUE_SHORT( psEncapHdr->iEncaph_command );

      /*
      ** Parse the encap command
      */
      en_cd_ProcessEncapMsg( &sUDPEce, psPacketBuf );

   }  /* End forever */
}  /* en_cd_UDPRecvTask */



/*---------------------------------------------------------------------------
** en_cd_PostListen( )
**---------------------------------------------------------------------------
*/

UINT32 en_cd_PostListen( void )
{
   UINT32          lFlagTrue = ~0;
   INT32           lSize_buf;
   UINT32          lSockFd, status;
   struct sockaddr_in sSrv_addr;

   if ( ( lSockFd = socket( PF_INET, SOCK_STREAM, 0 ) ) == OE_ERROR )
   {
      /*
      ** Socket error.  Without a socket we cannot do anything
      */

      GS_LogEvent( EN_SOCKET_ERR, OE_SOCKET_ERRNO,
                   0,
                   FATAL );
      GS_DeleteTask( 0 );
   }

   UC_SetMem( ( char * ) &sSrv_addr, 0, sizeof( sSrv_addr ) );
   sSrv_addr.sin_family = AF_INET;
   sSrv_addr.sin_addr.s_addr = htonl( INADDR_ANY );
   sSrv_addr.sin_port = htons( lEncapServerPort );

   /*
   **	Bind the server to TCP_PORT, which the client knows
   */

   status = setsockopt( lSockFd, SOL_SOCKET, SO_REUSEADDR, ( char * ) &lFlagTrue,
                       sizeof( lFlagTrue ) );

   if ( status == OE_ERROR )
   {
      /*
      ** While some of the options are non-critical, having them fail this
      ** early in the game should be a cause for general alarm
      */

      GS_LogEvent( EN_SOCKET_OPT,
                   OE_SOCKET_ERRNO,
                   0,
                   FATAL );
   }

   status = setsockopt( lSockFd, SOL_SOCKET, SO_KEEPALIVE, ( char * ) &lFlagTrue,
                       sizeof( lFlagTrue ) );

   if ( status == OE_ERROR )
   {
      GS_LogEvent( EN_SOCKET_OPT,
                   OE_SOCKET_ERRNO,
                   0,
                   FATAL );
   }

   /*
   ** Get a size buffer at least large enough for a full packet, and also
   ** keep it a power of 2. Keep it at least 4k in size
   */

   lSize_buf = TCP_RCV_BUF_SIZE;
   while ( lSize_buf < PKTBUF_MAX_DATA )
   {
      lSize_buf <<= 1;
   }

   status = setsockopt( lSockFd, SOL_SOCKET, SO_SNDBUF, ( char * ) &lSize_buf,
                        sizeof( lSize_buf ) );

   if ( status == OE_ERROR )
   {
      /*
      ** While some of the options are non-critical, having them fail this
      ** early in the game should be a cause for general alarm
      */

      GS_LogEvent( EN_SOCKET_OPT, OE_SOCKET_ERRNO,
                  0,
                  FATAL );
   }

   status = setsockopt( lSockFd,
                        SOL_SOCKET,
                        SO_RCVBUF,
                        ( char * ) &lSize_buf,
                        sizeof( lSize_buf ) );

   if ( status == OE_ERROR )
   {
      /*
      ** While some of the options are non-critical, having them fail this
      ** early in the game should be a cause for general alarm
      */

      GS_LogEvent( EN_SOCKET_OPT,
                   OE_SOCKET_ERRNO,
                   0,
                   FATAL );
   }

   if ( bind( lSockFd, ( struct sockaddr * ) & sSrv_addr, sizeof( sSrv_addr ) ) == OE_ERROR )
   {
      /*
      ** If we can't bind, no one can conect, fatal out
      */

      GS_LogEvent( EN_BIND_ERR,
                   OE_SOCKET_ERRNO,
                   0,
                   FATAL );
      GS_DeleteTask( 0 );
   }

   if ( listen( lSockFd, 5 ) == OE_ERROR )
   {
      /*
      ** If we can't bind, no one can conect, fatal out
      */

      GS_LogEvent( EN_LISTEN_ERR,
                   OE_SOCKET_ERRNO,
                   0,
                   FATAL );
      GS_DeleteTask( 0 );
   }

   return ( lSockFd );
}  /* end en_cd_PostListen( ) */


/*---------------------------------------------------------------------------
** en_cd_PassiveWaitTask( )
**---------------------------------------------------------------------------
*/

TASKRETURN en_cd_PassiveWaitTask( TASKPARAM )
{
   UINT8           achTaskName[32];
   struct sockaddr_in sCli_addr;
   ECE            *psEce;
   INT32           lSockFd, lSockFd2, lAddrLen;
   GS_TaskSeedType sSeed;
   OE_Q_ID            sSendTaskMsgQueue;
    INT32          nStatus;
   UINT32          lTaskID;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -