1.实验目标
以C++类封装socket
2.实验原理
类继承体系:
BasicFileSocketUnixSocketTcpSocketUdpSocketUnixStreamClientSocketUnixStreamServerSocketTcpClientSocketTcpServerSocketUdpClientSocketUdpServerSocket 3.实验内容
(1)socket表现为文件描述符
将int socket作为类的成员,类向外暴露各种socket操作 编写如下:
class Socket {
public:
Socket();
virtual ~Socket(); virtual int Socket(); private:
int sin_size; int sockfd,new_fd; unsigned short port;
struct sockaddr_in my_addr,their_addr,get_addr;
};
void SetPort(unsigned short in_port); bool Bind();
void SetRemotePort(unsigned short in_port); unsigned short GetRemotePort(); void GetRemoteAddrees(char *addrees); bool Connect(); void Listen(); void Accept();
int Send(const char *buf,int len); int Sendto(const char *buf,int len); int Recv(char *buf,int len); int Recvfrom(char *buf,int len); void Close();
//
class TCP:public Socket { };
class UDP:public Socket { };
class SCTP:public Socket {
public:
int Socket();
bool Connect(); public:
int Socket();
public:
int Socket(); bool Connect();
}; #endif
socket的类型很多 SOCK_STREAM SOCK_DGRAM SOCK_SEQPACKET AF_INET TCP|SCTP UDP SCTP AF_INET6 TCP|SCTP UDP SCTP AF_LOCAL yes yes yes 以一种统一的形式封装各种不同类型的socket 处理如下:
//定义
class TCP:public Socket {
};
public:
int Socket(); bool Connect();
class UDP:public Socket { };
class SCTP:public Socket {
public:
int Socket();
bool Connect(); public:
int Socket();
}; //函数
int UDP::Socket() {
sockfd = socket(AF_INET ,SOCK_DGRAM, 0); return sockfd; }
int TCP::Socket() {
sockfd = socket(AF_INET,SOCK_STREAM, 0); return sockfd; }
int SCTP::Socket() { }
sockfd = socket(AF_INET,SOCK_SEQPAKET, 0); return sockfd;
(2)考察socket的连接函数
socket的地址族不一样,导致sockaddr结构是不一样的,虽然tcp/sctp这样的面向连接的协议可能都会有connect这样的函数,并且连接的动作都差不多,但是connect函数的servaddr参数是不一样的。如何解决相似动作,但是参数类型不同? 处理如下:
bool TCP::Connect() {
if(connect(sockfd,(struct sockaddr *)&their_addr, sizeof(struct sockaddr))==-1)
return false;
return true; }
bool SCTP::Connect() {
if(connect(sockfd,(const struct sockaddr *)&their_addr, sizeof(struct sockaddr))==-1) return false;
return true; }
附录1 socket.h
#ifndef #define
#include #include private: int sin_size; int sockfd,new_fd; unsigned short port; struct sockaddr_in my_addr,their_addr,get_addr; SOCKET__H SOCKET__H }; public: Socket(); virtual ~Socket(); virtual int Socket(); void SetPort(unsigned short in_port); bool Bind(); void SetRemotePort(unsigned short in_port); unsigned short GetRemotePort(); void GetRemoteAddrees(char *addrees); bool Connect(); void Listen(); void Accept(); int Send(const char *buf,int len); int Sendto(const char *buf,int len); int Recv(char *buf,int len); int Recvfrom(char *buf,int len); void Close(); // class TCP:public Socket { }; class UDP:public Socket { }; class SCTP:public Socket { public: int Socket(); bool Connect(); public: int Socket(); public: int Socket(); bool Connect(); }; #endif 附录2 socket.cpp #include \"server.h\" Socket::Socket() { } Socket::~Socket() { Close(); } int UDP::Socket() { sockfd = socket(AF_INET ,SOCK_DGRAM, 0); return sockfd; } int TCP::Socket() { sockfd = socket(AF_INET,SOCK_STREAM, 0); return sockfd; } int SCTP::Socket() { sockfd = socket(AF_INET,SOCK_SEQPAKET, 0); return sockfd; } int Socket::Socket() { sockfd = socket(AF_INET,SOCK_STREAM, 0); return sockfd; } void Socket::SetPort(unsigned short in_port) { struct hostent *host; host=gethostbyname(\"192.168.0.225\"); my_addr.sin_family = AF_INET; port = in_port; my_addr.sin_port = htons(port); my_addr.sin_addr = *((struct in_addr *)host->h_addr); bzero(&(my_addr.sin_zero),8); } void Socket::SetRemotePort(unsigned short in_port) { their_addr.sin_port=htons(in_port); } unsigned short Socket::GetRemotePort() { return ntohs(get_addr.sin_port); } bool Socket::Bind() { if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1) { perror(\"bind err\\n\"); return false; } return true; } int Socket::Recvfrom(char *buf,int len) { int numbytes; socklen_t addr_len = sizeof(get_addr); numbytes = recvfrom(sockfd,buf,len,0,(struct sockaddr *)&get_addr,&addr_len); if(numbytes == -1) { return false; } buf[numbytes] = '\\0'; return numbytes; } int Socket::Sendto(const char *buf,int len) { return sendto(sockfd,buf,len,0,(struct sockaddr *)&their_addr,sizeof(struct sockaddr)); } void Socket::Close() { close(sockfd); close(new_fd); } void Socket::Listen() { if(listen(sockfd,10)==-1) cout<<\"listen err!\\n\"; } void Socket::Accept() { socklen_t size = sizeof(struct sockaddr_in); new_fd = accept(sockfd,(struct sockaddr *)&get_addr,&size); if(new_fd==-1) { perror(\"accept err!\\n\"); exit(1); } } int Socket::Recv(char *buf,int len) { return recv(new_fd,buf,len,0); } int Socket::Send(const char * buf, int len) { return send(new_fd,buf,len,0); } bool TCP::Connect() { if(connect(sockfd,(struct sockaddr *)&their_addr, sizeof(struct sockaddr))==-1) return false; return true; } bool SCTP::Connect() { if(connect(sockfd,(const struct sockaddr *)&their_addr, sizeof(struct sockaddr))==-1) return false; return true; } 因篇幅问题不能全部显示,请点此查看更多更全内容