来源:远方网络 | 2006-1-6 | (有1926人读过)
四、自定义的CMySocket类的实现代码:
根据上面的知识,我自定义了一个简单的CMySocket类,下面是我定义的该类的部分实现代码:
////////////////////////////////////// CMySocket::CMySocket() : file://类的构造函数 { WSADATA wsaD; memset( m_LastError, 0, ERR_MAXLENGTH ); // m_LastError是类内字符串变量,初始化用来存放最后错误说明的字符串; // 初始化类内sockaddr_in结构变量,前者存放客户端地址,后者对应于服务器端地址; memset( &m_sockaddr, 0, sizeof( m_sockaddr ) ); memset( &m_rsockaddr, 0, sizeof( m_rsockaddr ) ); int result = WSAStartup((WORD)((1<<8|1), &wsaD);//初始化WinSocket动态连接库; if( result != 0 ) // 初始化失败; { set_LastError( "WSAStartup failed!", WSAGetLastError() ); return; } }
////////////////////////////// CMySocket::~CMySocket() { WSACleanup(); }//类的析构函数; //////////////////////////////////////////////////// int CMySocket::Create( void ) {// m_hSocket是类内Socket对象,创建一个基于TCP/IP的Socket变量,并将值赋给该变量; if ( (m_hSocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP )) == INVALID_SOCKET ) { set_LastError( "socket() failed", WSAGetLastError() ); return ERR_WSAERROR; } return ERR_SUCCESS; } /////////////////////////////////////////////// int CMySocket::Close( void )//关闭Socket对象; { if ( closesocket( m_hSocket ) == SOCKET_ERROR ) { set_LastError( "closesocket() failed", WSAGetLastError() ); return ERR_WSAERROR; } file://重置sockaddr_in 结构变量; memset( &m_sockaddr, 0, sizeof( sockaddr_in ) ); memset( &m_rsockaddr, 0, sizeof( sockaddr_in ) ); return ERR_SUCCESS; } ///////////////////////////////////////// int CMySocket::Connect( char* strRemote, unsigned int iPort )//定义连接函数; { 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 CMySocket::Bind( char* strIP, unsigned int iPort )//绑定函数; { if( strlen( strIP ) == 0 || iPort == 0 ) return ERR_BADPARAM; memset( &m_sockaddr,0, sizeof( 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 CMySocket::Accept( SOCKET s )//建立连接函数,S为监听Socket对象名; { int Len = sizeof( m_rsockaddr ); memset( &m_rsockaddr, 0, sizeof( 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 CMySocket::asyncSelect( HWND hWnd, unsigned int wMsg, long lEvent ) file://事件选择函数; { 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 CMySocket::Listen( int iQueuedConnections )//监听函数; { 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 CMySocket::Send( char* strData, int iLen )//数据发送函数; { 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 CMySocket::Receive( char* strData, int iLen )//数据接收函数; { 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; } void CMySocket::set_LastError( char* newError, int errNum ) file://WinSock API操作错误字符串设置函数; { memset( m_LastError, 0, ERR_MAXLENGTH ); memcpy( m_LastError, newError, strlen( newError ) ); m_LastError[strlen(newError)+1] = '\0'; }
有了上述类的定义,就可以在网络程序的服务器和客户端分别定义CMySocket对象,建立连接,传送数据了。例如,为了在服务器和客户端发送数据,需要在服务器端定义两个CMySocket对象ServerSocket1和ServerSocket2,分别用于监听和连接,客户端定义一个CMySocket对象ClientSocket,用于发送或接收数据,如果建立的连接数大于一,可以在服务器端再定义CMySocket对象,但要注意连接数不要大于五。
由于Socket API函数还有许多,如获取远端服务器、本地客户机的IP地址、主机名等等,读者可以再此基础上对CMySocket补充完善,实现更多的功能。
|