Linux socket編程(一) 對套接字操作的封裝


以前寫的,現在回顧一下:

下面是對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 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; }

接下來是異常處理到類

#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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM