Linux socket编程(一) 对套接字操作的封装

来源:互联网 发布:温莎公爵间谍 知乎 编辑:程序博客网 时间:2024/05/20 22:38

转载: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 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

复制代码
#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 functionbool 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 Transmissionbool 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;}
复制代码

接下来是异常处理到类

复制代码
#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
复制代码
原创粉丝点击