技术开发 频道

基于Visual C++的Winsock API研究

    

  四、自定义的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补充完善,实现更多的功能。

0
相关文章