VC SOCKET

-

.H

/*******************************************
 * winSocket.h - Header file for winSocket * 
 *      Winsock API wrapper class          *
 *    Ryan Lederman ryan@winprog.org       *
 *            January 2002                 *
 *          THIS CODE IS FREE              *
 *                                         *
 ******************************************
*/

#ifndef _WINSOCKET_H
#define _WINSOCKET_H

#include 
"winsock.h"
#include 
"winbase.h"

#define ERR_SUCCESS  0x00000000    // Successful
#define ERR_BADPARAM 0x80000001    // Bad argument passed
#define ERR_WSAERROR 0x80000002    // Need to get_LastError()
#define ERR_MAXLENGTH 512

class winSocket    // Definition of winSocket
{
public:    // Public Methods
    winSocket::winSocket();        // Constructor
    winSocket::~winSocket();    // Destructor

    
int Create( void );                                                // Creates the socket
    int Close( void );                                                // Closes the socket
    int Connect( char* strRemote, unsigned int iPort );                // Connects the socket to a remote site
    int Send( SOCKET s, char* strData, int iLen );                    // Sends data
    int Send( char* strData, int iLen );    
    
int Receive( SOCKET s, char* strData, int iLen );                // Receives data
    int Receive( char* strData, int iLen );
    
int Listen( int iQueuedConnections );                            // Listen for connections
    int Bind( char* strIP, unsigned int iPort );                    // Binds to a port
    int Accept( SOCKET s );                                            // Accepts a connection
    int asyncSelect( HWND hWnd,                                        // Allows calling window to receive 
        unsigned int wMsg, long lEvent );                            // notifications (non-blocking sockets)                                        
    int get_LocalIP( char* strIP );                                    // Returns local IP address            
    int get_LocalPort( int* iPort );                                // Returns local Port number
    int get_RemoteIP( char* strIP );                                // Returns remote side IP
    int get_RemotePort( int* iPort );                                // Returns remote side Port number
    int get_LocalHost( char* strBuffer, int iBufLen );                // Returns local host name
    int get_RemoteHost( char* strBuffer, int iBufLen );                // Returns remote host name
    void get_LastError( char* strBuffer, int* iErrNum );            // Returns error information
    int set_SendTimeout( int ms );                                    // Sets send timeout, in milliseconds
    int set_RecvTimeout( int ms );                                    // Sets recv timeout, in milliseconds
    void longToDottedQuad( unsigned long ulLong, char* cBuffer );    // 32-bit long -> dotted quad
private:    // Private Methods
    void winSocket::set_LastError( char* newError, int errNum );    // Sets last error information
private:    // Private Members
    struct sockaddr_in m_sockaddr;        // Holds all data associated with socket
    struct sockaddr_in m_rsockaddr;        // Holds data associated with remote side
    WORD m_wVersion;                    // Version to use when calling WSAStartup
    char m_LastError[ERR_MAXLENGTH+1];    // Buffer that holds last error
    int     m_ErrorNumber;                    // Last error number
public:        // Public Members
    SOCKET m_hSocket;                    // Underlying SOCKET object
};

#endif /* _WINSOCKET_H */

.CPP

/*******************************************
 *   winSocket.cpp - Implementation of     * 
 *   winSocket Winsock API wrapper class   *
 *    Ryan Lederman ryan@winprog.org       *
 *            January 2002                 *
 *          THIS CODE IS FREE              *
 *                                         *
 ******************************************
*/

#include 
"winSocket.h"

winSocket::winSocket() : m_hSocket(
0),
                         m_wVersion(
0),
                         m_ErrorNumber(
0)        
{
    WSADATA wsaD;    
// Structure initialsed by WSAStartup
    m_wVersion = MAKEWORD(2,2);    // Version number requested

    memset( m_LastError, 
0, ERR_MAXLENGTH );    // Nullify last error
    memset( &m_sockaddr, 0sizeof( m_sockaddr ) );    // Nullify structures
    memset( &m_rsockaddr, 0sizeof( m_rsockaddr ) );

    
int result = WSAStartup( m_wVersion, &wsaD );    // Initialize Winsock
    
    
if( result != 0 ) // WSAStartup failed
    {
        set_LastError( 
"WSAStartup failed!", WSAGetLastError() );
        
return;
    }
}

winSocket::
~winSocket() { WSACleanup();    /* Un-initialise Winsock*/ }

int winSocket::Create( void )
{
    
/**************************************
    * FUNCTION: Create                    *
    *                                     *
    * PURPOSE: Initializes the underlying *
    * SOCKET object for the class.        *           
    *                                     * 
    * RETURNS: ERR_WSAERROR upon error,   *                 
    * otherwise ERR_SUCCESS               *   
    *                                     *
    **************************************
*/

    
if ( (m_hSocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP )) == INVALID_SOCKET )
    {
        set_LastError( 
"socket() failed", WSAGetLastError() );
        
return ERR_WSAERROR;
    }

    
return ERR_SUCCESS;    
}

int winSocket::Close( void )
{
    
/****************************************
    * FUNCTION: Close                       *
    *                                       *
    * PURPOSE: Closes the underlying        *
    * SOCKET object. Does not destroy class *           
    *                                       * 
    * RETURNS: ERR_WSAERROR upon error,     *                  
    * otherwise ERR_SUCCESS                 *   
    *                                       *
    ****************************************
*/

    
if ( closesocket( m_hSocket ) == SOCKET_ERROR )
    {
        set_LastError( 
"closesocket() failed", WSAGetLastError() );
        
return ERR_WSAERROR;
    }

    memset( 
&m_sockaddr, 0sizeof( sockaddr_in ) );
    memset( 
&m_rsockaddr, 0sizeof( sockaddr_in ) );

    
return ERR_SUCCESS;
}

int winSocket::Connect( char* strRemote, unsigned int iPort )
{
    
/*****************************************
    * FUNCTION: Connect                      *
    *                                        *
    * PURPOSE: Establishes TCP/IP connection *
    * with remote host (strRemote) on port   *     
    * # (iPort)                              *
    *                                        *
    * RETURNS: ERR_BADPARAM for invalid      *
    * parameters, ERR_WSAERROR upon error,   *
    * otherwise ERR_SUCCESS                  *
    *                                        *
    *****************************************
*/

    
if( strlen( strRemote ) == 0 || iPort == 0 )
        
return ERR_BADPARAM;

    hostent 
*hostEnt = NULL;
    
long lIPAddress = 0;

    hostEnt 
= gethostbyname( strRemote );

    
if( hostEnt != NULL )
    {
        lIPAddress 
= ((in_addr*)hostEnt->h_addr)->s_addr;
        m_sockaddr.sin_addr.s_addr 
= lIPAddress;
    }
    
else
    {
        m_sockaddr.sin_addr.s_addr 
= inet_addr( strRemote );
    }

    m_sockaddr.sin_family 
= AF_INET;
    m_sockaddr.sin_port 
= htons( iPort );

    
if( connect( m_hSocket, (SOCKADDR*)&m_sockaddr, sizeof( m_sockaddr ) ) == SOCKET_ERROR )
    {
        set_LastError( 
"connect() failed", WSAGetLastError() );
        
return ERR_WSAERROR;
    }

    
return ERR_SUCCESS;
}

int winSocket::Listen( int iQueuedConnections )
{
    
/*****************************************
    * FUNCTION: Listen                       *
    *                                        *
    * PURPOSE: Places the SOCKET in the      *
    * listening state. Requires that Bind()  *
    * be called previously.                  *
    *                                        *
    * RETURNS: ERR_BADPARAM for invalid      *
    * parameters, ERR_WSAERROR upon error,   *
    * otherwise ERR_SUCCESS                  *
    *                                        *
    *****************************************
*/

    
if( iQueuedConnections == 0 )
        
return ERR_BADPARAM;

    
if( listen( m_hSocket, iQueuedConnections ) == SOCKET_ERROR )
    {
        set_LastError( 
"listen() failed", WSAGetLastError() );
        
return ERR_WSAERROR;
    }

    
return ERR_SUCCESS;
}

int winSocket::Send( SOCKET s, char* strData, int iLen )
{
    
/**********************************************
    * FUNCTION: Send                              *
    *                                             *
    * PURPOSE: Sends data (strData) to remote     *
    * side on socket s.                           *
    *                                             *
    * RETURNS: ERR_BADPARAM for invalid           *
    * parameters, ERR_WSAERROR upon error,        *
    * otherwise ERR_SUCCESS                       *
    *                                             *
    **********************************************
*/

    
if( strData == NULL || iLen == 0 )
        
return ERR_BADPARAM;

    
if( send( s, strData, iLen, 0 ) == SOCKET_ERROR )
    {
        set_LastError( 
"send() failed", WSAGetLastError() );
        
return ERR_WSAERROR;
    }
    
    
return ERR_SUCCESS;
}

int winSocket::Send( char* strData, int iLen )
{
    
/**********************************************
    * FUNCTION: Send                              *
    *                                             *
    * PURPOSE: Sends data (strData) to remote     *
    * side on an established TCP/IP connection.   *
    * Requires that Connect be called previously. *
    *                                             *
    * RETURNS: ERR_BADPARAM for invalid           *
    * parameters, ERR_WSAERROR upon error,        *
    * otherwise ERR_SUCCESS                       *
    *                                             *
    **********************************************
*/

    
if( strData == NULL || iLen == 0 )
        
return ERR_BADPARAM;

    
if( send( m_hSocket, strData, iLen, 0 ) == SOCKET_ERROR )
    {
        set_LastError( 
"send() failed", WSAGetLastError() );
        
return ERR_WSAERROR;
    }
    
    
return ERR_SUCCESS;
}

int winSocket::Receive( SOCKET s, char* strData, int iLen )
{
    
/***********************************************
    * FUNCTION: Receive                            *
    *                                              *
    * PURPOSE: Retreives data from incoming queue  *
    * and copies to (strData). (iLen) will contain *
    * the length of data read in bytes             *
    *                                              *
    * RETURNS: ERR_BADPARAM for invalid            *
    * parameters, ERR_WSAERROR upon error,         *
    * otherwise passes what recv() returns.        *
    *                                              *
    **********************************************
*/

    
if( strData == NULL )
        
return ERR_BADPARAM;

    
int len = 0;
    
int ret = 0;
    
    ret 
= recv( s, strData, iLen, 0 );

    
if ( ret == SOCKET_ERROR )
    {
        set_LastError( 
"recv() failed", WSAGetLastError() );
        
return ERR_WSAERROR;
    }
    
return ret;
}

int winSocket::Receive( char* strData, int iLen )
{
    
/***********************************************
    * FUNCTION: Receive                            *
    *                                              *
    * PURPOSE: Retreives data from incoming queue  *
    * and copies to (strData). (iLen) will contain *
    * the length of data read in bytes             *
    *                                              *
    * RETURNS: ERR_BADPARAM for invalid            *
    * parameters, ERR_WSAERROR upon error,         *
    * otherwise passes what recv() returns.        *
    *                                              *
    **********************************************
*/

    
if( strData == NULL )
        
return ERR_BADPARAM;

    
int len = 0;
    
int ret = 0;
    
    ret 
= recv( m_hSocket, strData, iLen, 0 );

    
if ( ret == SOCKET_ERROR )
    {
        set_LastError( 
"recv() failed", WSAGetLastError() );
        
return ERR_WSAERROR;
    }

    
return ret;
}

int winSocket::Bind( char* strIP, unsigned int iPort )
{
    
/************************************************
    * FUNCTION: Bind                                *
    *                                               *
    * PURPOSE: Associates the SOCKET object with an *
    * IP address (strIP) and port number (iPort)    *
    *                                               *
    * RETURNS: ERR_BADPARAM for invalid             *
    * parameters, ERR_WSAERROR upon error,          *
    * otherwise ERR_SUCCESS                         *
    *                                               *
    ***********************************************
*/

    
if( strlen( strIP ) == 0 || iPort == 0 )
        
return ERR_BADPARAM;

    memset( 
&m_sockaddr,0sizeof( m_sockaddr ) );
    m_sockaddr.sin_family 
= AF_INET;
    m_sockaddr.sin_addr.s_addr 
= inet_addr( strIP );
    m_sockaddr.sin_port 
= htons( iPort );

    
if ( bind( m_hSocket, (SOCKADDR*)&m_sockaddr, sizeof( m_sockaddr ) ) == SOCKET_ERROR )
    {
        set_LastError( 
"bind() failed", WSAGetLastError() );
        
return ERR_WSAERROR;
    }
    
return ERR_SUCCESS;
}

int winSocket::Accept( SOCKET s )
{    
    
/***************************************************
    * FUNCTION: Accept                                 *
    *                                                  *
    * PURPOSE: Initializes the SOCKET object (if not   *
    * previously initialized), associates the SOCKET   *
    * object with the IP address and port of the       *
    * remote side, and accepts an incoming connection. *
    * Usually called from a Window Procedure using     *
    * wParam as the argument.                          *
    *                                                  *
    * RETURNS: ERR_WSAERROR upon error,                *
    * otherwise ERR_SUCCESS                            *
    *                                                  *
    ***************************************************
*/

    
int Len = sizeof( m_rsockaddr );

    memset( 
&m_rsockaddr, 0sizeof( m_rsockaddr ) );

    
if( ( m_hSocket = accept( s, (SOCKADDR*)&m_rsockaddr, &Len ) ) == INVALID_SOCKET )
    {
        set_LastError( 
"accept() failed", WSAGetLastError() );
        
return ERR_WSAERROR;
    }

    
return ERR_SUCCESS;
}

int winSocket::asyncSelect( HWND hWnd, unsigned int wMsg, long lEvent )
{
    
/**************************************************
    * FUNCTION: asyncSelect                           *
    *                                                 *
    * PURPOSE: Enables Windows Messaging notification *
    * for the object. (wMsg) will be sent to the      *
    * Window Procedure of (hWnd) whenever one of the  *
    * events in (lEvent) has occurred. See MSDN docs  *
    * for WSAAsyncSelect() for more information.      *
    *                                                 *
    * RETURNS: ERR_BADPARAM for invalid               *
    * parameters, ERR_WSAERROR upon error,            *
    * otherwise ERR_SUCCESS                           *
    *                                                 *
    **************************************************
*/

    
if!IsWindow( hWnd ) || wMsg == 0 || lEvent == 0 )
        
return ERR_BADPARAM;

    
if( WSAAsyncSelect( m_hSocket, hWnd, wMsg, lEvent ) == SOCKET_ERROR )
    {
        set_LastError( 
"WSAAsyncSelect() failed", WSAGetLastError() );
        
return ERR_WSAERROR;
    }
    
return ERR_SUCCESS;
}

int winSocket::get_RemoteIP( char* strIP )
{
    
/*************************************************
    * FUNCTION: get_RemoteIP                         *
    *                                                *
    * PURPOSE: Copies the IP address for the remote  *
    * side on an established TCP/IP connection into  *
    * (strIP).                                       *
    *                                                *
    * RETURNS: ERR_BADPARAM for invalid parameters,  *
    * ERR_WSAERROR upon error, otherwise ERR_SUCCESS *
    *                                                *
    *************************************************
*/

    
if( strIP == NULL )
        
return ERR_BADPARAM;

    
int namelen = sizeof( m_rsockaddr );

    
if( getpeername( m_hSocket, (SOCKADDR*)&m_rsockaddr, &namelen ) == SOCKET_ERROR )
    {
        set_LastError( 
"getpeername() failed", WSAGetLastError() );
        
return ERR_WSAERROR;
    }

    longToDottedQuad( m_rsockaddr.sin_addr.s_addr, strIP );

    
return ERR_SUCCESS;
}

int winSocket::get_RemotePort( int* iPort )
{
    
/*************************************************
    * FUNCTION: get_RemotePort                       *
    *                                                *
    * PURPOSE: Copies the port number for the remote *
    * side on an established TCP/IP connection into  *
    * (iPort).                                       *
    *                                                *
    * RETURNS: ERR_BADPARAM for invalid parameters,  *
    * ERR_WSAERROR upon error, otherwise ERR_SUCCESS *
    *                                                *
    *************************************************
*/

    
if( iPort == NULL )
        
return ERR_BADPARAM;

    
int namelen = sizeof( m_rsockaddr );
    
    
if( getpeername( m_hSocket, (SOCKADDR*)&m_rsockaddr, &namelen ) == SOCKET_ERROR )
    {
        set_LastError( 
"getpeername() failed", WSAGetLastError() );
        
return ERR_WSAERROR;
    }

    
*iPort = ntohs( m_rsockaddr.sin_port );

    
return ERR_SUCCESS;
}

int winSocket::get_LocalHost( char* strBuffer, int iBufLen )
{
    
/*************************************************
    * FUNCTION: get_LocalHost                        *
    *                                                *
    * PURPOSE: Copies the fully qualified host name  *
    * for the local machine into (strBuffer). Will   *
    * fail if returned data is longer than (iBufLen).*
    *                                                *
    * RETURNS: ERR_BADPARAM for invalid parameters,  *
    * ERR_WSAERROR upon error, otherwise ERR_SUCCESS *
    *                                                *
    *************************************************
*/

    
if( strBuffer == NULL )
        
return ERR_BADPARAM;

    
char strHost[512= {0};
    hostent
* hostEnt = NULL;
    
int iLen = 0;

    gethostname( strHost, 
512 );
    hostEnt 
= gethostbyname( strHost );

    
if( hostEnt == NULL )
        
return ERR_WSAERROR;

    iLen 
= strlen( hostEnt->h_name );

    
if( iLen > iBufLen )
        
return ERR_BADPARAM;

    memset( strBuffer, 
0, iBufLen );
    memcpy( strBuffer, hostEnt
->h_name, iLen );

    
return ERR_SUCCESS;
}

int winSocket::get_RemoteHost( char* strBuffer, int iBufLen )
{
    
/*************************************************
    * FUNCTION: get_RemoteHost                       *
    *                                                *
    * PURPOSE: Copies the fully qualified host name  *
    * of the remote side (on a connected socket)     *
    * into (strBuffer). Will fail if data returned   *
    * is longer than iBufLen.                        *
    *                                                *
    * RETURNS: ERR_BADPARAM for invalid parameters,  *
    * ERR_WSAERROR upon error, otherwise ERR_SUCCESS *
    *                                                *
    *************************************************
*/

    
if( strBuffer == NULL )
        
return ERR_BADPARAM;

    hostent
* hostEnt = NULL;
    
int iLen = 0;
    
int namelen = sizeof( m_rsockaddr );

    
if( getpeername( m_hSocket, (SOCKADDR*)&m_rsockaddr, &namelen ) == SOCKET_ERROR )
        
return ERR_WSAERROR;

    hostEnt 
= gethostbyaddr( (char*)&m_rsockaddr.sin_addr.s_addr, 4 ,PF_INET );

    
if( hostEnt != NULL )
    {
        iLen 
= strlen( hostEnt->h_name );
        
if( iLen > iBufLen )
            
return ERR_BADPARAM;

        memcpy( strBuffer, hostEnt
->h_name, iLen );
        
return ERR_SUCCESS;
    }

    
return ERR_WSAERROR;
}

int winSocket::get_LocalIP( char* strIP )
{
    
/*************************************************
    * FUNCTION: get_LocalIP                          *
    *                                                *
    * PURPOSE: Copies the IP address for the local   *
    * machine into (strIP). Requires that Connect or *
    * Bind be called previously                      *
    *                                                *
    * RETURNS: ERR_BADPARAM for invalid parameters,  *
    * otherwise ERR_SUCCESS                          *
    *                                                *
    *************************************************
*/

    
if( strIP == NULL )
        
return ERR_BADPARAM;
    
    
int  namelen = sizeof( m_sockaddr );
    HOSTENT
* hEnt = NULL;
    
char szHostName[512= {0};
    
char szIP[16= {0};
    
char szAddrField[4= {0};
    unsigned 
int ufield = 0;

    
if( getsockname( m_hSocket, (SOCKADDR*)&m_sockaddr, &namelen ) == SOCKET_ERROR )
        
return ERR_WSAERROR;

    longToDottedQuad( m_sockaddr.sin_addr.s_addr, strIP );

    
return ERR_SUCCESS;
}

int winSocket::get_LocalPort( int* iPort )
{
    
/*****************************************************
    * FUNCTION: get_LocalPort                            *
    *                                                    *
    * PURPOSE: Copies the local port number associated   *
    * with the SOCKET object into (iPort).               *
    * Requires that Connect or Bind be called previously *
    *                                                    *
    * RETURNS: ERR_BADPARAM for invalid parameters,      *
    * otherwise ERR_SUCCESS                              *
    *                                                    *
    *****************************************************
*/

    
if( iPort == NULL )
        
return ERR_BADPARAM;

    
*iPort = ntohs(m_sockaddr.sin_port);

    
return ERR_SUCCESS;
}

int winSocket::set_SendTimeout( int ms )
{
    
/*****************************************************
    * FUNCTION: set_SendTimeout                          *
    *                                                    *
    * PURPOSE: Sets the amount of time the socket will   *
    * wait before returning WSAETIMEDOUT when calling    *
    * Send(). Set to 0 for infinite (default)            *
    *                                                    *
    * RETURNS: ERR_BADPARAM for invalid parameters,      *
    * ERR_WSAERROR for a winsock error,                  *
    * otherwise ERR_SUCCESS                              *
    *                                                    *
    *****************************************************
*/
    
    
if( ms < 0 )
        
return ERR_BADPARAM;

    
if( setsockopt( m_hSocket, SOL_SOCKET, SO_SNDTIMEO, (char*)&ms, sizeof( ms ) ) == SOCKET_ERROR )
    {
        set_LastError( 
"setsockopt() failed.", WSAGetLastError() );
        
return ERR_WSAERROR;
    }

    
return ERR_SUCCESS;
}

int winSocket::set_RecvTimeout( int ms )
{
    
/*****************************************************
    * FUNCTION: set_RecvTimeout                          *
    *                                                    *
    * PURPOSE: Sets the amount of time the socket will   *
    * wait before returning WSAETIMEDOUT when calling    *
    * Receive(). Set to 0 for infinite (default)         *
    *                                                    *
    * RETURNS: ERR_BADPARAM for invalid parameters,      *
    * ERR_WSAERROR for a winsock error,                  *
    * otherwise ERR_SUCCESS                              *
    *                                                    *
    *****************************************************
*/
    
    
if( ms < 0 )
        
return ERR_BADPARAM;

    
if( setsockopt( m_hSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&ms, sizeof( ms ) ) == SOCKET_ERROR )
    {
        set_LastError( 
"setsockopt() failed.", WSAGetLastError() );
        
return ERR_WSAERROR;
    }

    
return ERR_SUCCESS;
}

void winSocket::set_LastError( char* newError, int errNum )
{
    
/**************************************************
    * FUNCTION: set_LastError                         *
    *                                                 *
    * PURPOSE: Sets error information for the object. *
    *                                                 *
    * RETURNS: None.                                  *
    *                                                 *
    **************************************************
*/

    memset( m_LastError, 
0, ERR_MAXLENGTH ); 
    memcpy( m_LastError, newError, strlen( newError ) );
    m_LastError[strlen(newError)
+1= '\0';
    m_ErrorNumber 
= errNum;
}

void winSocket::get_LastError( char* strBuffer, int* iErrNum )
{
    
/***************************************************
    * FUNCTION: get_LastError                          *
    *                                                  *
    * PURPOSE: Retreives description and number of the *
    * last error that occurred. Copies into (strBuffer)*
    * and (iErrNum), repsectively.                     *
    *                                                  *
    * RETURNS: None.                                   *
    *                                                  *
    ***************************************************
*/

    
int len = strlen( m_LastError );

    
if( len > 0 )
    {
        memset( strBuffer, 
0, len );
        memcpy( strBuffer, m_LastError, len );
        strBuffer[len
+1= '\0';
        
*iErrNum = m_ErrorNumber;
    }
}

void winSocket::longToDottedQuad( unsigned long ulLong, char* cBuffer )
{
    
/*****************************************************
    * FUNCTION: longToDottedQuad                         *
    *                                                    *
    * PURPOSE: Translates an IP address from 32-bit long *
    * to dotted quad form (255.255.255.255). Translates  *
    * (ulLong) and copies results to (cBuffer).          *
    *                                                    *
    * RETURNS: None.                                     *
    *                                                    *
    *****************************************************
*/

    wsprintf( cBuffer, 
"%d.%d.%d.%d",(int)((BYTE*)&ulLong)[0],
        (
int)((BYTE*)&ulLong)[1],(int)((BYTE*)&ulLong)[2],(int)((BYTE*)&ulLong)[3] );
}
原文地址:https://www.cnblogs.com/xianqingzh/p/1457741.html