电脑爱好者,提供IT资讯信息及各类编程知识文章介绍,欢迎大家来本站学习电脑知识。 最近更新 | 联系我们 RSS订阅本站最新文章
电脑爱好者
站内搜索: 
当前位置:首页>> C++/VC>>基于Visual C++的Winsock API研究二:

基于Visual C++的Winsock API研究二

来源:远方网络 | 2006-1-6 | (有1957人读过)


  四、自定义的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补充完善,实现更多的功能。
C++/VC热门文章排行
网站赞助商
购买此位置

 

关于我们 | 网站地图 | 文档一览 | 友情链接| 联系我们

Copyright © 2003-2024 电脑爱好者 版权所有 备案号:鲁ICP备09059398号