linux에서 비저항 모드 네트워크 통신 모델 예시 공유

11500 단어
 
  
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#ifdef __ENABLED_DEBUG_INFO_OUTPUT__
    #define DEBUG_OUTPUT(format) printf( "
File: %s : Line: %d ->Function: %s
"format"
", __BASE_FILE__, __LINE__, __FUNCTION__ )
    #define DEBUG_OUTPUT_PARA(format,...) printf( "
File: %s : Line: %d ->Function: %s
"format"
", __BASE_FILE__, __LINE__, __FUNCTION__, __VA_ARGS__ )
#else
    #define DEBUG_OUTPUT(format)
    #define DEBUG_OUTPUT_PARA(format,...)
#endif

// @brief /
// @param[in] sockfd
// @param[in] bWhichSet true - ; false - ;
// @param[in] uiTimeOutMS ( : );
// @pre scokfd , (>=0)
// @return
// @return  0 - / ;
//         -1 - ;
//         -2 - ;
// @note uiTimeOutMS , (0),
static inline int
wait_rw_able( int          sockfd,
              bool         bWhichSet,
              unsigned int uiTimeOutMS )
{
    //
    int iReturnValue = -2;

    //
    fd_set rset;
    //
    fd_set wset;

    // select
    timeval tv;

    do // ,
    {
        //
        if ( 0 > sockfd )
        {
            iReturnValue = -1;
            break;
        }

        // : select !
        tv.tv_sec  = 0;
        tv.tv_usec = uiTimeOutMS;

        //
        if ( true == bWhichSet )
        {
            //
            FD_ZERO( &rset );
            //
            FD_SET( sockfd, &rset );

            // (0) - , (0) - , -
            if ( 0 < select( sockfd + 1, // (0) , (1)
                             &rset,      //
                             NULL,       //
                             NULL,       //
                             &tv ) )     //
            {
                //
                if ( FD_ISSET( sockfd, &rset ) )
                {
                    iReturnValue = 0;
                    break;
                }
            }
        }
        //
        else
        {
            //
            FD_ZERO( &wset );
            //
            FD_SET( sockfd, &wset );

            // (0) - , (0) - , -
            if ( 0 < select( sockfd + 1, // (0) , (1)
                             NULL,       //
                             &wset,      //
                             NULL,       //
                             &tv ) )     //
            {
                //
                if ( FD_ISSET( sockfd,
                               &wset ) )
                {
                    iReturnValue = 0;
                    break;
                }
            }
        }

    }while( 0 );

    return iReturnValue;
}

// @brief
// @param[int][out] pucSRBuffer
// @param[int] usBufferLen
// @pre pucSRBuffer , (0)
// @return
// @retval   0
// @retval  -1
// @retval  -2
// @retval  -3
// @retval  -4
// @retval  -5 getsockopt
// @retval  -6 connect
// @retval  -7
// @retval  -8
// @retval  -9
// @retval -10 recv
// @retval -11 pucSRBuffer
int
send_receive_data( unsigned char* const pucSRBuffer,
                   const unsigned short usBufferLen )
{
    //
    int         iResult = 0; // (0)

    // TCP
    int         iServerSocket = -1;
    // IP
    sockaddr_in sServerAddr;

    // I/O
    int iValue = 1;

    //
    int       iSo_Error = 0;
    socklen_t So_Error_len = sizeof( iSo_Error );

    //
    unsigned short usRealReceivedData = 0;

    do // ,
    {
        // 1.
        if ( ( NULL == pucSRBuffer ) ||
             (    0 >= usBufferLen ) ||
             (    0 == pucSRBuffer[0] ) )
        {
            DEBUG_OUTPUT( "Invalid parameter" );

            iResult = -1;
            break;
        }

        // 2.
        iServerSocket = socket( AF_INET,     // IPv4
                                SOCK_STREAM, // TCP 
                                0 );         // , (0)
        if ( 0 > iServerSocket )
        {
            DEBUG_OUTPUT( "Create socket is failed" );

            iResult = -2;
            break;
        }

        // 3. connect ,
        iValue = 1; //
        iResult = ioctl( iServerSocket, //
                         FIONBIO,       // I/O
                         &iValue );     // (0) - , (0) -
        if ( 0 > iResult )
        {
            DEBUG_OUTPUT_PARA( "Call ioctl to set I/O asynchronization is failed, return %d",
                               iResult );

            iResult = -3;
            break;
        }

        sServerAddr.sin_family = AF_INET;
        inet_pton( AF_INET,
                   m_caServerIP,
                   &sServerAddr.sin_addr );
        sServerAddr.sin_port = htons( m_usServerPort );

        // 4.
        iResult = connect( iServerSocket,
                           (sockaddr*)&sServerAddr,
                           sizeof( sServerAddr ) );
        // connect , , TCP ,
        // , EINPROGRESS ,
        // 。
        if ( 0 != iResult ) // (0)
        {
            // connect 75 , 750 。
            // : , , , 。
            iResult = wait_rw_able( iServerSocket,
                                    false,     //
                                    750000  ); // 750
            if ( 0 != iResult )
            {
                DEBUG_OUTPUT( "Can't write in asynchronization" );

                iResult = -4;
                break;
            }

            if ( 0 > getsockopt( iServerSocket,
                                 SOL_SOCKET,
                                 SO_ERROR,
                                 &iSo_Error,
                                 &So_Error_len ) )
            {
                DEBUG_OUTPUT( "Call getsockopt is failed" );

                iResult = -5;
                break;
            }

            // (0)
            if ( 0 != iSo_Error )
            {
                DEBUG_OUTPUT( "Call connect is failed" );

                iResult = -6;
                break;
            }
        }

        // 5. connect , ( )
        iValue = 0;
        iResult = ioctl( iServerSocket, //
                         FIONBIO,       // I/O
                         &iValue );     // (0) - , (0) -
        if ( 0 > iResult )
        {
            DEBUG_OUTPUT_PARA( "Call ioctl to set I/O synchronization is failed, return %d",
                               iResult );

            iResult = -7;
            break;
        }

        // 6.
        iResult = send( iServerSocket,
                        (const char*)pucSRBuffer,
                        strlen( (const char*)pucSRBuffer ),
                        0 );
        //
        if ( iResult != (int)strlen( (const char*)pucSRBuffer ) )
        {
            DEBUG_OUTPUT( "Call send is failed" );

            iResult = -8;
            break;
        }

        // 7. -
        iResult = wait_rw_able( iServerSocket, //
                                true,          //
                                750000  );     // 750
        if ( 0 != iResult )
        {
            DEBUG_OUTPUT( "Waitting for recevie data has time out" );

            iResult = -9;
            break;
        }

        // (0),
        memset( pucSRBuffer, 0, usBufferLen );
        do
        {
            // 8.
            iResult = recv( iServerSocket,                        //
                            pucSRBuffer + usRealReceivedData,     //
                            usBufferLen - usRealReceivedData - 1, //
                            0 );                                  // (0),
            // ,
            if ( 0 > iResult )
            {
                DEBUG_OUTPUT_PARA( "Call recv is failed, return %d", iResult );

                iResult = -10;
                break;
            }

              // (0)
              if ( 0 == iResult )
              {
                  break;
              }

            usRealReceivedData += iResult;

            //
            if ( usBufferLen <= usRealReceivedData )
            {
                DEBUG_OUTPUT( "pucSRBuffer is not superfluous space" );

                iResult = -11;
                break;
            }

        }while( 0 == wait_rw_able( iServerSocket,
                                   true,        //
                                   750000  ) ); // 750

        // ,
        if ( 0 > iResult )
        {
            break;
        }

        //
        iResult = 0;
        break;

    }while( 0 );

    // ,
    if ( -1 != iServerSocket )
    {
        close( iServerSocket );
    }

    return iResult;
}

좋은 웹페이지 즐겨찾기