以前写的,现在回顾一下:
下面是对socket操作的封装,因为在Linux下写中文到了windows里面会乱码,所以注释用英文来写,有空再查下解决方法吧
socket.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
#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 destructior virtual ~Socket(); // Server initialization bool Create(); //create a socket bool Bind(const int port); bool Listen() const; bool Accept(Socket& clientSocket) const; // Client initialization bool Connect(const std::string& host,const int port); // Data Transmission bool 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 socket int m_sockfd; struct sockaddr_in m_address; }; #endif |
这里解释下为什么析构函数是虚的,如果要用到多态的话,也就是用一个指向基类的指针来处理对不同到对象
如果类的成员函数不是虚函数,只是个普通的函数,那么会出现一种静态绑定到情况,如
Base* pBase = new Derive; //这里Base的析构函数不是虚函数
delete pBase; //这里只会调用Base::~Base(),所以派生类部分的资源将得不到释放
如果析构函数是虚函数的话,那么将调用Derive::~Derive(),由于我们提供了派生类的析构函数,编译器会扩展这个析构函数,
在里面调用基类的析构函数,这样派生类和基类的资源都将得到释放
socket.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
#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 functions bool 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 -1 return m_sockfd!=-1; } |
接下来是异常处理到类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#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 |
发表评论
要发表评论,您必须先登录。