跨平台Socket封装 odsocket

本文介绍了一个跨平台的套接字类库ODSocket的设计与实现。该库旨在为Windows和Linux提供统一的网络编程接口,支持创建、连接、监听等操作,并提供了错误处理和域名解析等功能。

 

odsocket.h:

/*  
* define file about portable socket class.   
* description:this sock is suit both windows and linux  
* design:odison  
* e-mail:odison@126.com>  
*   
*/   

#ifndef _ODSOCKET_H_ 
#define _ODSOCKET_H_   

#ifdef WIN32  

#include <winsock.h>  
typedef int    socklen_t; 
#else  
#include <sys/socket.h>  
#include <netinet/in.h>  
#include <netdb.h>  
#include <fcntl.h>  
#include <unistd.h>  
#include <sys/stat.h>  
#include <sys/types.h>  
#include <arpa/inet.h>  

typedef int    SOCKET;    

//#pragma region define win32 const variable in linux  
#define INVALID_SOCKET -1  
#define SOCKET_ERROR -1  

//#pragma endregion 
#endif     

class ODSocket
{   
 public:  
  ODSocket(SOCKET sock = INVALID_SOCKET);  
  ~ODSocket();    
  
  // Create socket object for snd/recv data  
  bool Create(int af, int type, int protocol = 0);    
  
  // Connect socket  
  bool Connect(const char* ip, unsigned short port);  
  
  #region server  
  // Bind socket  
  bool Bind(unsigned short port);    
  
  // Listen socket  
  bool Listen(int backlog = 5);     
  
  // Accept socket  
  bool Accept(ODSocket& s, char* fromip = NULL);  
  
  #endregion     
  
  // Send socket  
  int Send(const char* buf, int len, int flags = 0);    
  
  // Recv socket  
  int Recv(char* buf, int len, int flags = 0);     
  
  // Close socket  
  int Close();    
  
  // Get errno  
  int GetError();     
  //#pragma region just for win32  
  // Init winsock DLL   
  static int Init();   
  // Clean winsock DLL  
  static int Clean();  
  //#pragma endregion    
  // Domain parse  
  static bool DnsParse(const char* domain, char* ip);    
  
  ODSocket& operator = (SOCKET s);    
  
  operator SOCKET ();   
  
 protected:  
  SOCKET m_sock;   
};   

#endif

===========================================================================

odsocket.cpp

 

/*  
* Source file about portable socket class.   
*  
* design:odison  
* e-mail:odison@126.com>  
*   
*/       

#include  
#include  
#include "odsocket.h"   

#ifdef WIN32  
#pragma comment(lib, "wsock32") 
#endif     

ODSocket::ODSocket(SOCKET sock) 
{  
 m_sock = sock; 
}   

ODSocket::~ODSocket() 

}   

int ODSocket::Init() 

#ifdef WIN32  
/*   http://msdn.microsoft.com/zh-cn/vstudio/ms741563(en-us,VS.85).aspx    
 typedef struct WSAData
 {    
  WORD wVersion;       
  //winsock version   
  WORD wHighVersion;      
  //The highest version of the Windows Sockets specification that the Ws2_32.dll can support   
  char szDescription[WSADESCRIPTION_LEN+1];    
  char szSystemStatus[WSASYSSTATUS_LEN+1];    
  unsigned short iMaxSockets;    
  unsigned short iMaxUdpDg;    
  char FAR * lpVendorInfo;   
 }WSADATA, *LPWSADATA;   
*/ 
 WSADATA wsaData;  
 //#define MAKEWORD(a,b) ((WORD) (((BYTE) (a)) | ((WORD) ((BYTE) (b))) << 8))   
 WORD version = MAKEWORD(2, 0);  
 int ret = WSAStartup(version, &wsaData);
 
 //win sock start up  
 if ( ret )
 {   
  cerr << "Initilize winsock error !" << endl;    return -1;  
 } 
#endif     
 return 0; 

//this is just for windows 
int ODSocket::Clean() 

#ifdef WIN32   
 return (WSACleanup()); 
#endif   
 return 0; 
}   

ODSocket& ODSocket::operator = (SOCKET s) 
{  
 m_sock = s;  
 return (*this); 
}   

ODSocket::operator SOCKET () 
{  
 return m_sock; 

//create a socket object win/lin is the same 
// af: 
bool ODSocket::Create(int af, int type, int protocol) 
{  
 m_sock = socket(af, type, protocol);  
 if ( m_sock == INVALID_SOCKET )
 {   
  return false;  
 }  
 
 return true; 
}   

bool ODSocket::Connect(const char* ip, unsigned short port) 
{  
 struct sockaddr_in svraddr;  
 svraddr.sin_family = AF_INET;  
 svraddr.sin_addr.s_addr = inet_addr(ip);  
 svraddr.sin_port = htons(port);  
 
 int ret = connect(m_sock, (struct sockaddr*)&svraddr, sizeof(svraddr));  
 
 if ( ret == SOCKET_ERROR )
 {   
  return false;  
 }  
 
 return true; 
}   

bool ODSocket::Bind(unsigned short port) 
{  
 struct sockaddr_in svraddr;  
 svraddr.sin_family = AF_INET;  
 svraddr.sin_addr.s_addr = INADDR_ANY;  
 svraddr.sin_port = htons(port);    
 
 int opt =  1;  
 
 if ( setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof(opt)) < 0 )    
  return false;    
  
 int ret = bind(m_sock, (struct sockaddr*)&svraddr, sizeof(svraddr));  
 if ( ret == SOCKET_ERROR )
 {   
  return false;  
 }  
 
 return true;

//for server 
bool ODSocket::Listen(int backlog) 
{  
 int ret = listen(m_sock, backlog);  
 if ( ret == SOCKET_ERROR )
 {   
  return false;  
 }  
 return true; 
}   

bool ODSocket::Accept(ODSocket& s, char* fromip) 
{  
 struct sockaddr_in cliaddr;  
 socklen_t addrlen = sizeof(cliaddr);  
 SOCKET sock = accept(m_sock, (struct sockaddr*)&cliaddr, &addrlen);  
 
 if ( sock == SOCKET_ERROR )
 {   
  return false;  
 }    
 
 s = sock;  
 if ( fromip != NULL )   
  sprintf(fromip, "%s", inet_ntoa(cliaddr.sin_addr));    
 
 return true; 
}   

int ODSocket::Send(const char* buf, int len, int flags) 
{  
 int bytes;  
 int count = 0;    
 
 while ( count < len )
 {     
  bytes = send(m_sock, buf + count, len - count, flags);   
  
  if ( bytes == -1 || bytes == 0 )    
   return -1;   
   
  count += bytes;  
 }     
 
 return count; 
}   

int ODSocket::Recv(char* buf, int len, int flags) 
{  
 return (recv(m_sock, buf, len, flags)); 
}   

int ODSocket::Close() 

#ifdef WIN32  
 return (closesocket(m_sock)); 
#else  
 return (close(m_sock)); 
#endif 
}   

int ODSocket::GetError() 

#ifdef WIN32  
 return (WSAGetLastError()); 
#else  
 return (errno); 
#endif 
}   

bool ODSocket::DnsParse(const char* domain, char* ip) 
{  
 struct hostent* p;  
 if ( (p = gethostbyname(domain)) == NULL )   
  return false;      
  
 sprintf(ip,    
   "%u.%u.%u.%u",   
   (unsigned char)p->h_addr_list[0][0],    
   (unsigned char)p->h_addr_list[0][1],    
   (unsigned char)p->h_addr_list[0][2],    
   (unsigned char)p->h_addr_list[0][3]);     
 
 return true; 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值