Linux socket 类封装 (面向对象方法)
1 /* 2 * socketfactory.h 3 * 4 * Created on: 2014-7-19 5 * Author: root 6 */ 7 8 #ifndef SOCKETFACTORY_H_ 9 #define SOCKETFACTORY_H_ 10 #include<sys/types.h> 11 12 /* 13 * 在网路编程中, 一般分为服务端和客户端,两者的行为有相似之处,也有非常多的不同。在linux中对socket程序设计 14 * 仅提供了socket(), bind(), connection(), accept() listern() 几个函数,并未区分是服务端还是客户端。 15 * 在java或其他高级语言中,一般都对socket进行了封装,简化使用。 16 * 此端程序将linux socket进行封装在三个类中。一个工厂类,两个接口类。 17 * 18 */ 19 20 namespace socketfactory { 21 22 class ISocket; 23 class IServerSocket; 24 25 /* 26 * SocketFactory 负责创建 ISocket, IServerSocket 的实例,同时负责销毁实例。 27 * SocketFactory的方法全部是静态方法。此处采用了工厂模式。 28 * 29 */ 30 class SocketFactory { 31 public: 32 static ISocket* createSocket(const char* tIP, int tPort); /* 创建客户端 socket */ 33 static IServerSocket* createServerSocket(int port); /* 创建服务端 socket */ 34 static int destroy(ISocket* psocket); /* 销毁 */ 35 static int destroy(IServerSocket* psocket); /* 销毁 */ 36 }; 37 38 /* 39 * ISocket 为接口,定义为纯虚类。面向接口编程 40 * 41 */ 42 43 class ISocket { 44 public: 45 virtual int read(void* buf, size_t len)=0; /* 读取对端数据 */ 46 virtual int write(void* buf, size_t len)=0; /* 写入对端数据 */ 47 virtual int close()=0; /* 关闭连接 */ 48 }; 49 50 /* 51 * IServerSocket 为接口,定义为纯虚类。面向接口编程。 52 * 53 */ 54 55 class IServerSocket { 56 public: 57 virtual ISocket* accept()=0; /* 接受连接,返回与对端通信的socket */ 58 virtual int listen(int backlog)=0; /* 启动服务端口 监听 */ 59 virtual int close()=0; /* 关闭 服务端 socket */ 60 }; 61 62 } 63 64 #endif /* SOCKETFACTORY_H_ */
实现类的头文件
1 /* 2 * socketimpl.h 3 * 4 * Created on: 2014-7-20 5 * Author: root 6 */ 7 8 #ifndef SOCKETIMPL_H_ 9 #define SOCKETIMPL_H_ 10 #include <sys/socket.h> 11 #include <netinet/in.h> 12 #include "socketfactory.h" 13 14 using namespace socketfactory; 15 16 /* 17 * ISocket 和 IServerSocket 的实现类。 18 * SocketFactory工厂类创建这些实现类。 19 * 20 */ 21 22 class SocketImpl: public ISocket 23 { 24 public: 25 int read(void* buf, size_t len); 26 int write(void* buf, size_t len); 27 int close(); 28 29 int ssocket(int domain, int type, int protocol); 30 int cconnect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 31 SocketImpl(); 32 virtual ~SocketImpl(); 33 34 public: 35 int fd; 36 struct sockaddr address; 37 }; 38 39 40 class ServerSocketImpl: public IServerSocket 41 { 42 public: 43 ISocket* accept(); 44 int listen(int backlog); 45 int close(); 46 47 48 int ssocket(int domain, int type, int protocol); 49 int bbind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 50 ServerSocketImpl(); 51 virtual ~ServerSocketImpl(); 52 53 public: 54 int fd; 55 struct sockaddr address; 56 }; 57 58 59 #endif /* SOCKETIMPL_H_ */
1 /* 2 * socketimpl.cpp 3 * 4 * Created on: 2014-7-20 5 * Author: root 6 */ 7 8 #include <unistd.h> 9 #include "socketimpl.h" 10 #include <sys/types.h> 11 #include <sys/socket.h> 12 13 #include <stdio.h> 14 15 16 SocketImpl::SocketImpl() { 17 this->fd = -1; 18 } 19 20 int SocketImpl::ssocket(int domain, int type, int protocol) { 21 this->fd = socket(domain, type, protocol); 22 if (this->fd < 0) 23 perror("SocketImpl::ssocket"); 24 return this->fd; 25 } 26 27 int SocketImpl::cconnect(int sockfd, const struct sockaddr *addr, 28 socklen_t addrlen) { 29 int ret = connect(sockfd, addr, addrlen); 30 if (ret != 0) 31 perror("SocketImpl::cconnect"); 32 return ret; 33 34 } 35 36 SocketImpl::~SocketImpl() { 37 38 } 39 40 int SocketImpl::read(void* buf, size_t len) { 41 int ret = ::read(this->fd, buf, len); 42 if (ret < 0) 43 perror("SocketImpl::read"); 44 return ret; 45 } 46 ; 47 48 int SocketImpl::write(void* buf, size_t len) { 49 int ret = ::write(this->fd, buf, len); 50 if (ret < 0) 51 perror("SocketImpl::write"); 52 return ret; 53 } 54 ; 55 56 int SocketImpl::close() { 57 if (this->fd > 0) { 58 int ret = ::close(this->fd); 59 if (ret != 0) 60 { 61 perror("SocketImpl::close"); 62 return ret; 63 }else 64 this->fd = -1; 65 } 66 return 0; 67 } 68 69 ServerSocketImpl::ServerSocketImpl() { 70 this->fd = 0; 71 } 72 73 ServerSocketImpl::~ServerSocketImpl() { 74 } 75 76 int ServerSocketImpl::ssocket(int domain, int type, int protocol) { 77 this->fd = socket(domain, type, protocol); 78 if (this->fd < 0) 79 perror("ServerSocketImpl::ssocket"); 80 return this->fd; 81 } 82 83 int ServerSocketImpl::bbind(int sockfd, const struct sockaddr *addr, 84 socklen_t addrlen) { 85 int ret = bind(this->fd, addr, addrlen); 86 if (ret < 0) 87 perror("ServerSocketImpl::bbind"); 88 return ret; 89 } 90 91 ISocket* ServerSocketImpl::accept() { 92 SocketImpl* nsocket = new SocketImpl(); 93 int addlen=0; 94 int nfd = ::accept(this->fd, &nsocket->address, (socklen_t*)&addlen); 95 if (nfd == -1) { 96 delete nsocket; 97 perror("ServerSocketImpl::accept"); 98 return NULL; 99 } 100 nsocket->fd = nfd; 101 return nsocket; 102 } 103 104 int ServerSocketImpl::listen(int backlog) { 105 int ret = ::listen(this->fd, backlog); 106 if (ret < 0) 107 perror("ServerSocketImpl::listen"); 108 return ret; 109 } 110 111 int ServerSocketImpl::close() { 112 if(this->fd >0 ) 113 { 114 int ret=::close(this->fd); 115 if(ret!=0 ) 116 { 117 perror("ServerSocketImpl::close"); 118 return ret; 119 }else 120 this->fd =-1; 121 } 122 return 0; 123 }
/* * socketfactory.cpp * * Created on: 2014-7-20 * Author: root */ #include "socketfactory.h" #include "socketimpl.h" #include <sys/socket.h> #include <netinet/in.h> #include <string.h> #include <stdio.h> #include <arpa/inet.h> ISocket* SocketFactory::createSocket(const char* tIP, int tPort) { SocketImpl* nsocket=new SocketImpl(); memset(&nsocket->address, 0, sizeof(sockaddr)); struct sockaddr_in* padd=(sockaddr_in*)(&nsocket->address); padd->sin_family=AF_INET; padd->sin_port=htons(tPort); if( inet_pton(AF_INET, tIP, &padd->sin_addr) <= 0){ delete nsocket; perror("SocketFactory::createSocket:inet_pton"); return NULL; } int ret=nsocket->ssocket(AF_INET, SOCK_STREAM, 0); if(ret < 0 ){ perror("SocketFactory::createSocket:ssocket"); delete nsocket; return NULL; } ret=nsocket->cconnect(nsocket->fd, &nsocket->address, sizeof(sockaddr)); if(ret < 0 ){ perror("SocketFactory::createSocket:cconnect"); nsocket->close(); delete nsocket; return NULL; } return nsocket; } IServerSocket* SocketFactory::createServerSocket(int port) { ServerSocketImpl *nssocket=new ServerSocketImpl(); memset(&nssocket->address, 0, sizeof(sockaddr)); struct sockaddr_in* padd=(sockaddr_in*)(&nssocket->address); padd->sin_family=AF_INET; padd->sin_addr.s_addr=htonl(INADDR_ANY); padd->sin_port=htons(port); int ret=nssocket->ssocket(AF_INET, SOCK_STREAM, 0); if(ret<0){ perror("SocketFactory::createServerSocket:ssocket"); delete nssocket; return NULL; } ret=nssocket->bbind(nssocket->fd, &nssocket->address, sizeof(sockaddr)); if(ret<0){ perror("SocketFactory::createServerSocket:bbind"); nssocket->close(); delete nssocket; return NULL; } return nssocket; } int SocketFactory::destroy(ISocket* psocket) { SocketImpl* psockimpl=(SocketImpl*)psocket; psockimpl->close(); delete psockimpl; return 0; } int SocketFactory::destroy(IServerSocket* psocket) { ServerSocketImpl* pssocket=(ServerSocketImpl*)psocket; pssocket->close(); delete pssocket; return 0; }