轉自:http://www.cnblogs.com/-Lei/archive/2012/09/04/2670942.html
下面是對socket操作的封裝,因為在Linux下寫中文到了windows里面會亂碼,所以注釋用英文來寫,有空再查下解決方法吧
socket.h
#ifndef SOCKET_H #define SOCKET_H#include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string>const int MAXCONNECTION=5; const int MAXRECEIVE = 500;class Socket {public:Socket();//virtual destructiorvirtual ~Socket();// Server initializationbool Create(); //create a socketbool Bind(const int port);bool Listen() const;bool Accept(Socket& clientSocket) const;// Client initializationbool Connect(const std::string& host,const int port);// Data Transmissionbool Send(Socket& socket,const std::string& message) const;int Receive(Socket& socket,std::string& message) const;void SetNonBlocking(const bool flag);bool IsValid() const;private://use m_sockfd to record the result of function socketint m_sockfd;struct sockaddr_in m_address; };#endif
這里解釋下為什么析構函數是虛的,如果要用到多態的話,也就是用一個指向基類的指針來處理對不同到對象
如果類的成員函數不是虛函數,只是個普通的函數,那么會出現一種靜態綁定到情況,如
Base* pBase = new Derive; //這里Base的析構函數不是虛函數
delete pBase; //這里只會調用Base::~Base(),所以派生類部分的資源將得不到釋放
如果析構函數是虛函數的話,那么將調用Derive::~Derive(),由于我們提供了派生類的析構函數,編譯器會擴展這個析構函數,
在里面調用基類的析構函數,這樣派生類和基類的資源都將得到釋放
?
socket.cpp
#include "Socket.h" #include <stdlib.h> #include <memory.h> #include <iostream> #include <fcntl.h>Socket::Socket() :m_sockfd(-1) { }Socket::~Socket() {if(IsValid())::close(m_sockfd); }//server function bool Socket::Create() {m_sockfd=socket(AF_INET,SOCK_STREAM,0);if(!IsValid())return false;return true; }bool Socket::Bind(const int port) {if(!IsValid())return false;m_address.sin_family=AF_INET;m_address.sin_addr.s_addr = htonl(INADDR_ANY);m_address.sin_port=htons(port);int bindReturn=bind(m_sockfd,(struct sockaddr*)&m_address,sizeof(m_address));if(bindReturn==-1)return false;return true; }bool Socket::Listen()const {if(!IsValid())return false;int listenReturn=listen(m_sockfd,MAXCONNECTION);if(listenReturn ==-1)return false;return true; }bool Socket::Accept(Socket& clientSocket) const {int clientaddrLength=sizeof(clientSocket.m_address);clientSocket.m_sockfd=::accept(m_sockfd,(struct sockaddr*)&clientSocket.m_address,(socklen_t *)&clientaddrLength);if(clientSocket.m_sockfd==-1)return false;return true; } //end server functionsbool Socket::Connect(const std::string& host,const int port) {if(!IsValid())return false;m_address.sin_family=AF_INET;m_address.sin_port=htons(port);m_address.sin_addr.s_addr=inet_addr(host.c_str());int connectReturn=::connect(m_sockfd,(struct sockaddr*)&m_address,sizeof(m_address));if(connectReturn==-1)return false;return true;}// Data Transmission bool Socket::Send(Socket& socket,const std::string& message) const {int result=::send(socket.m_sockfd,message.c_str(),message.length(),MSG_NOSIGNAL);if(result==-1)return false;return true; }int Socket::Receive(Socket& socket,std::string& message) const {char buffer[MAXRECEIVE+1];message.clear();memset(buffer,0,MAXRECEIVE+1);int numberRead=::recv(socket.m_sockfd,buffer,MAXRECEIVE,0);if(numberRead==-1){std::cout<<"error in Socket::Receive\n";return 0;}else if(numberRead==0)return 0;else{message=buffer;return numberRead;}}void Socket::SetNonBlocking(const bool flag) {if(IsValid())
?? ?{
?? ??? ?? int opts;
?? ??? ?? opts = fcntl ( m_sockfd,
?? ??? ??? ??? ? F_GETFL );
?? ??? ?? if ( opts < 0 )
?? ??? ???? {
?? ??? ?????? return;
?? ??? ???? }
?? ??? ?? if ( flag )
?? ??? ???? opts = ( opts | O_NONBLOCK );
?? ??? ?? else
?? ??? ???? opts = ( opts & ~O_NONBLOCK );
?? ??? ?? fcntl ( m_sockfd,
?? ??? ??? ?? F_SETFL,opts );
?? ?}
}bool Socket::IsValid() const {//if call function socket fail,it returns -1return m_sockfd!=-1; }
接下來是異常處理到類
#ifndef SocketException_H #define SocketException_H#include <string>class SocketException {public:SocketException ( std::string description ) : m_description( description ) {};~SocketException (){};std::string Description() { return m_description; }private:std::string m_description; };#endif