作者在 2010-07-04 03:15:29 发布以下内容
呵呵,昨天对Windows下的Socket API进行了简单的封装,今天趁热打铁把Linux下的Socket也一起封装了到了一个类中,相比昨天的那个类,只是做了少些修改,增加了一些宏,废话 不多说了,看下面代码,(顺便带上一个简单的聊天代码Linux和Windows对聊的)。如果用C++的异常对出错进行处理就更好了,呵呵,有时间在添 加上^_^
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef __SOCKET_H__
#define __SOCKET_H__
#define __WINDOWS__
#include <string>
using namespace std;
#if defined (__WINDOWS__)
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
typedef int socklen;
#elif defined(__LINUX__)
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <errno.h>
#include <unistd.h>
typedef int SOCKET;
typedef socklen_t socklen;
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define closesocket close
#endif
typedef struct sockaddr SOCKADDR;
typedef struct sockaddr_in SOCKADDR_IN;
struct Host
{
string ip;
int port;
};
class Socket
{
public:
enum Type {TCP = SOCK_STREAM, UDP = SOCK_DGRAM};
public:
Socket(int type = SOCK_STREAM, int af = AF_INET, int protocol = 0);
Socket(const char *ip, int port,int type = SOCK_STREAM,int af = AF_INET, int protocol = 0);
Socket(const string &ip, int port, int type = SOCK_STREAM,int af = AF_INET, int protocol = 0);
Socket& operator=(const Socket &other);
virtual ~Socket();
static int InitSocket(int x = 2, int y = 2, WSADATA *wsa = NULL);
static int ClearSocket();
public:
int Create(int type = SOCK_STREAM,int af = AF_INET,int protocol = 0); //creat socket
int Bind(int port);
int Listen(int backlog = 5);
Socket Accept(void);
Socket* Accept(Socket *socket);
// try connect to remote host
int Connect(const char *ip, int port);
int Connect(const string &ip, int port);
int Connect();
// close previous connection and connect to another socket
int Reconnect(const char *ip, int port);
// send data to peer
int Send(const char* buf, int len = -1, int flags = 0);
int Send(const string &buf,int flags = 0);
int Receive(char* buf, int len, int flags = 0);
//UDP
int SendTo(char *ip, int port,const char* buf, int len = -1, int flags = 0);
int SendTo(char *ip, int port,const string &str,int flags = 0);
int ReceiveFrom(char *buf, int len, Host *host = NULL, int flags = 0);
// close connection
int Close(void);
public:
char* GetIP() const
{
return inet_ntoa(m_remoteaddr.sin_addr);
}
int GetPort() const
{
return m_remoteaddr.sin_port;
}
int GetBindPort() const
{
return this->m_bindPort;
}
SOCKET GetSocket() const
{
return this->m_SocketId;
}
protected:
string m_ip; //Remote Host IP
int m_port; //Remote Host port
int m_bindPort; //bind on local port
SOCKET m_SocketId;
SOCKADDR_IN m_remoteaddr; //Remote Host address info
};
#endif
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "Socket.h"
#include <assert.h>
int Socket::InitSocket(int x, int y, WSADATA *wsa)
{
#if defined (__WINDOWS__)
WSADATA wsaData;
return WSAStartup(MAKEWORD(x,y), ( NULL == wsa ) ? &wsaData : wsa);
#elif defined(__LINUX__)
return 1;
#endif
}
int Socket::ClearSocket()
{
#if defined (__WINDOWS__)
return WSACleanup();
#elif defined(__LINUX__)
return 1;
#endif
}
Socket::Socket(int type, int af, int protocol)
{
this->m_bindPort = 0;
this->m_port = 0;
this->m_SocketId = INVALID_SOCKET;
this->Create(type,af,protocol);
memset(&this->m_remoteaddr,0,sizeof(SOCKADDR_IN));
}
Socket& Socket::operator =(const Socket &other)
{
if( this != &other )
{
this->m_bindPort = other.m_bindPort;
this->m_ip = other.m_ip;
this->m_port = other.m_port;
this->m_SocketId = other.m_SocketId;
memcpy(&this->m_remoteaddr,&other.m_remoteaddr,sizeof(SOCKADDR_IN));
}
return *this;
}
Socket::Socket(const char *ip, int port,int type,int af, int protocol)
{
this->m_bindPort = 0;
this->m_port = port;
this->m_ip = ip;
this->m_SocketId = INVALID_SOCKET;
this->Create(type,af,protocol);
memset(&this->m_remoteaddr,0,sizeof(SOCKADDR_IN));
m_remoteaddr.sin_family = AF_INET;
m_remoteaddr.sin_port = htons(port);
m_remoteaddr.sin_addr.s_addr = inet_addr(ip);
}
Socket::Socket(const string &ip, int port,int type,int af, int protocol)
{
Socket(ip.c_str(),port,type,af,protocol);
}
Socket::~Socket()
{
this->Close();
}
int Socket::Create(int type, int af, int protocol)
{
if( INVALID_SOCKET != this->m_SocketId )
{
this->Close();
}
return (this->m_SocketId = socket(af,type,protocol)) == INVALID_SOCKET ;
}
int Socket::Close()
{
if( INVALID_SOCKET == this->m_SocketId )
{
closesocket(this->m_SocketId);
}
return 0;
}
int Socket::Bind(int port)
{
this->m_bindPort = port;
m_remoteaddr.sin_family = AF_INET;
m_remoteaddr.sin_addr.s_addr = htons(INADDR_ANY); //inet_addr("127.0.0.1");
m_remoteaddr.sin_port = htons(port);
return bind(this->m_SocketId,(SOCKADDR*)&m_remoteaddr,sizeof(SOCKADDR)); //绑定
}
int Socket::Listen(int backlog)
{
return listen(this->m_SocketId,backlog);
}
Socket Socket::Accept()
{
Socket remot;
socklen len = sizeof(SOCKADDR_IN);
remot.m_SocketId = accept(this->m_SocketId,(sockaddr *)&remot.m_remoteaddr,&len);
return remot;
}
Socket* Socket::Accept(Socket *socket)
{
assert( socket != NULL );
socklen len = sizeof(SOCKADDR_IN);
socket->m_SocketId = accept(this->m_SocketId,(sockaddr *)&socket->m_remoteaddr,&len);
return socket;
}
int Socket::Connect(const char *ip, int port)
{
this->m_ip = ip;
this->m_port = port;
return this->Connect();
}
int Socket::Connect(const string &ip, int port)
{
this->m_ip = ip.c_str();
this->m_port = port;
return this->Connect();
}
int Socket::Connect()
{
this->m_remoteaddr.sin_family = AF_INET;
this->m_remoteaddr.sin_addr.s_addr = inet_addr( this->m_ip.c_str() );
this->m_remoteaddr.sin_port = htons(m_port);
return connect(this->m_SocketId,(const struct sockaddr *)&this->m_remoteaddr,sizeof(m_remoteaddr));
}
int Socket::Reconnect(const char *ip, int port)
{
this->Close();
this->Create();
this->m_ip = ip;
this->m_port = port;
return this->Connect();
}
int Socket::Send(const char *buf, int len, int flags)
{
int lens = (int)(( len == -1 ) ? strlen(buf)+1 : len);
return send(this->m_SocketId,buf,lens,flags);
}
int Socket::Send(const string &buf, int flags)
{
return send(this->m_SocketId,buf.c_str(),(int)buf.length()+1,flags);
}
int Socket::Receive(char *buf, int len, int flags)
{
return recv(this->m_SocketId,buf,len,flags);
}
int Socket::SendTo(char *ip, int port,const char *buf, int len, int flags)
{
int lens = (int)((len == -1) ? strlen(buf)+1 : len);
m_remoteaddr.sin_addr.s_addr = inet_addr(ip);
m_remoteaddr.sin_family = AF_INET;
m_remoteaddr.sin_port = htons(port);
return sendto(this->m_SocketId,buf,lens,flags,(const sockaddr *)&m_remoteaddr,sizeof(sockaddr_in));
}
int Socket::SendTo(char *ip, int port,const string &str,int flags)
{
return this->SendTo(ip,port,str.c_str(),(int)str.length()+1,flags);
}
int Socket::ReceiveFrom(char *buf, int len, Host *host, int flags)
{
socklen lens = sizeof(sockaddr_in);
sockaddr_in sockadd;
int count = recvfrom(this->m_SocketId,buf,len,flags,(sockaddr*)&sockadd,&lens);
if( NULL != host )
{
host->ip = inet_ntoa(sockadd.sin_addr);
host->port = sockadd.sin_port;
}
return count;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
这个是运行在Windows下的客户端代码
#include "Socket.h"
#include <iostream>
using namespace std;
void main()
{
Socket::InitSocket();
Socket client;
client.Connect("172.16.24.247",4128);
char buf[100];
while( 1 )
{
cout<<"Input string:";
cin>>buf;
client.Send(buf);
client.Receive(buf,100);
cout<<"Server Say:"<<buf<<endl;
}
Socket::ClearSocket();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
下面是运行在Linux下的服务端:
#include "Socket.h"
#include <iostream>
using namespace std;
int main()
{
Socket server;
server.Bind(4128);
server.Listen();
Socket client;
server.Accept(&client);
char buf[100];
while( 1 )
{
client.Receive(buf,100);
cout<<client.GetIP()<<" Say:"<<buf<<endl;
cout<<"Input string:";
cin>>buf;
client.Send(buf);
}
}
#ifndef __SOCKET_H__
#define __SOCKET_H__
#define __WINDOWS__
#include <string>
using namespace std;
#if defined (__WINDOWS__)
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
typedef int socklen;
#elif defined(__LINUX__)
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <errno.h>
#include <unistd.h>
typedef int SOCKET;
typedef socklen_t socklen;
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define closesocket close
#endif
typedef struct sockaddr SOCKADDR;
typedef struct sockaddr_in SOCKADDR_IN;
struct Host
{
string ip;
int port;
};
class Socket
{
public:
enum Type {TCP = SOCK_STREAM, UDP = SOCK_DGRAM};
public:
Socket(int type = SOCK_STREAM, int af = AF_INET, int protocol = 0);
Socket(const char *ip, int port,int type = SOCK_STREAM,int af = AF_INET, int protocol = 0);
Socket(const string &ip, int port, int type = SOCK_STREAM,int af = AF_INET, int protocol = 0);
Socket& operator=(const Socket &other);
virtual ~Socket();
static int InitSocket(int x = 2, int y = 2, WSADATA *wsa = NULL);
static int ClearSocket();
public:
int Create(int type = SOCK_STREAM,int af = AF_INET,int protocol = 0); //creat socket
int Bind(int port);
int Listen(int backlog = 5);
Socket Accept(void);
Socket* Accept(Socket *socket);
// try connect to remote host
int Connect(const char *ip, int port);
int Connect(const string &ip, int port);
int Connect();
// close previous connection and connect to another socket
int Reconnect(const char *ip, int port);
// send data to peer
int Send(const char* buf, int len = -1, int flags = 0);
int Send(const string &buf,int flags = 0);
int Receive(char* buf, int len, int flags = 0);
//UDP
int SendTo(char *ip, int port,const char* buf, int len = -1, int flags = 0);
int SendTo(char *ip, int port,const string &str,int flags = 0);
int ReceiveFrom(char *buf, int len, Host *host = NULL, int flags = 0);
// close connection
int Close(void);
public:
char* GetIP() const
{
return inet_ntoa(m_remoteaddr.sin_addr);
}
int GetPort() const
{
return m_remoteaddr.sin_port;
}
int GetBindPort() const
{
return this->m_bindPort;
}
SOCKET GetSocket() const
{
return this->m_SocketId;
}
protected:
string m_ip; //Remote Host IP
int m_port; //Remote Host port
int m_bindPort; //bind on local port
SOCKET m_SocketId;
SOCKADDR_IN m_remoteaddr; //Remote Host address info
};
#endif
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "Socket.h"
#include <assert.h>
int Socket::InitSocket(int x, int y, WSADATA *wsa)
{
#if defined (__WINDOWS__)
WSADATA wsaData;
return WSAStartup(MAKEWORD(x,y), ( NULL == wsa ) ? &wsaData : wsa);
#elif defined(__LINUX__)
return 1;
#endif
}
int Socket::ClearSocket()
{
#if defined (__WINDOWS__)
return WSACleanup();
#elif defined(__LINUX__)
return 1;
#endif
}
Socket::Socket(int type, int af, int protocol)
{
this->m_bindPort = 0;
this->m_port = 0;
this->m_SocketId = INVALID_SOCKET;
this->Create(type,af,protocol);
memset(&this->m_remoteaddr,0,sizeof(SOCKADDR_IN));
}
Socket& Socket::operator =(const Socket &other)
{
if( this != &other )
{
this->m_bindPort = other.m_bindPort;
this->m_ip = other.m_ip;
this->m_port = other.m_port;
this->m_SocketId = other.m_SocketId;
memcpy(&this->m_remoteaddr,&other.m_remoteaddr,sizeof(SOCKADDR_IN));
}
return *this;
}
Socket::Socket(const char *ip, int port,int type,int af, int protocol)
{
this->m_bindPort = 0;
this->m_port = port;
this->m_ip = ip;
this->m_SocketId = INVALID_SOCKET;
this->Create(type,af,protocol);
memset(&this->m_remoteaddr,0,sizeof(SOCKADDR_IN));
m_remoteaddr.sin_family = AF_INET;
m_remoteaddr.sin_port = htons(port);
m_remoteaddr.sin_addr.s_addr = inet_addr(ip);
}
Socket::Socket(const string &ip, int port,int type,int af, int protocol)
{
Socket(ip.c_str(),port,type,af,protocol);
}
Socket::~Socket()
{
this->Close();
}
int Socket::Create(int type, int af, int protocol)
{
if( INVALID_SOCKET != this->m_SocketId )
{
this->Close();
}
return (this->m_SocketId = socket(af,type,protocol)) == INVALID_SOCKET ;
}
int Socket::Close()
{
if( INVALID_SOCKET == this->m_SocketId )
{
closesocket(this->m_SocketId);
}
return 0;
}
int Socket::Bind(int port)
{
this->m_bindPort = port;
m_remoteaddr.sin_family = AF_INET;
m_remoteaddr.sin_addr.s_addr = htons(INADDR_ANY); //inet_addr("127.0.0.1");
m_remoteaddr.sin_port = htons(port);
return bind(this->m_SocketId,(SOCKADDR*)&m_remoteaddr,sizeof(SOCKADDR)); //绑定
}
int Socket::Listen(int backlog)
{
return listen(this->m_SocketId,backlog);
}
Socket Socket::Accept()
{
Socket remot;
socklen len = sizeof(SOCKADDR_IN);
remot.m_SocketId = accept(this->m_SocketId,(sockaddr *)&remot.m_remoteaddr,&len);
return remot;
}
Socket* Socket::Accept(Socket *socket)
{
assert( socket != NULL );
socklen len = sizeof(SOCKADDR_IN);
socket->m_SocketId = accept(this->m_SocketId,(sockaddr *)&socket->m_remoteaddr,&len);
return socket;
}
int Socket::Connect(const char *ip, int port)
{
this->m_ip = ip;
this->m_port = port;
return this->Connect();
}
int Socket::Connect(const string &ip, int port)
{
this->m_ip = ip.c_str();
this->m_port = port;
return this->Connect();
}
int Socket::Connect()
{
this->m_remoteaddr.sin_family = AF_INET;
this->m_remoteaddr.sin_addr.s_addr = inet_addr( this->m_ip.c_str() );
this->m_remoteaddr.sin_port = htons(m_port);
return connect(this->m_SocketId,(const struct sockaddr *)&this->m_remoteaddr,sizeof(m_remoteaddr));
}
int Socket::Reconnect(const char *ip, int port)
{
this->Close();
this->Create();
this->m_ip = ip;
this->m_port = port;
return this->Connect();
}
int Socket::Send(const char *buf, int len, int flags)
{
int lens = (int)(( len == -1 ) ? strlen(buf)+1 : len);
return send(this->m_SocketId,buf,lens,flags);
}
int Socket::Send(const string &buf, int flags)
{
return send(this->m_SocketId,buf.c_str(),(int)buf.length()+1,flags);
}
int Socket::Receive(char *buf, int len, int flags)
{
return recv(this->m_SocketId,buf,len,flags);
}
int Socket::SendTo(char *ip, int port,const char *buf, int len, int flags)
{
int lens = (int)((len == -1) ? strlen(buf)+1 : len);
m_remoteaddr.sin_addr.s_addr = inet_addr(ip);
m_remoteaddr.sin_family = AF_INET;
m_remoteaddr.sin_port = htons(port);
return sendto(this->m_SocketId,buf,lens,flags,(const sockaddr *)&m_remoteaddr,sizeof(sockaddr_in));
}
int Socket::SendTo(char *ip, int port,const string &str,int flags)
{
return this->SendTo(ip,port,str.c_str(),(int)str.length()+1,flags);
}
int Socket::ReceiveFrom(char *buf, int len, Host *host, int flags)
{
socklen lens = sizeof(sockaddr_in);
sockaddr_in sockadd;
int count = recvfrom(this->m_SocketId,buf,len,flags,(sockaddr*)&sockadd,&lens);
if( NULL != host )
{
host->ip = inet_ntoa(sockadd.sin_addr);
host->port = sockadd.sin_port;
}
return count;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
这个是运行在Windows下的客户端代码
#include "Socket.h"
#include <iostream>
using namespace std;
void main()
{
Socket::InitSocket();
Socket client;
client.Connect("172.16.24.247",4128);
char buf[100];
while( 1 )
{
cout<<"Input string:";
cin>>buf;
client.Send(buf);
client.Receive(buf,100);
cout<<"Server Say:"<<buf<<endl;
}
Socket::ClearSocket();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
下面是运行在Linux下的服务端:
#include "Socket.h"
#include <iostream>
using namespace std;
int main()
{
Socket server;
server.Bind(4128);
server.Listen();
Socket client;
server.Accept(&client);
char buf[100];
while( 1 )
{
client.Receive(buf,100);
cout<<client.GetIP()<<" Say:"<<buf<<endl;
cout<<"Input string:";
cin>>buf;
client.Send(buf);
}
}
呵呵,付上贴图吧!