C++ 简单socket服务器实现文件list

参考网上的实现方式,先实现一个初始的SOCKET类及客户端,服务器的继承类,后续打算实现C++ epoll的框架。现在把文件贴在下面

基类Socket.h, Socket.cpp

#ifndef _E_SOCKET_H_
#define _E_SOCKET_H_


#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "basetype.h"


using namespace std;

const unsigned int BUFF_SIZE_1024 = 1024;
const unsigned int BUFF_SIZE_2048 = 2048;
/*
typedef union tagSOCK_ADDR
{
    struct sockaddr_in m_addr;
    struct addrinfo hints;
}SOCK_ADDR_U;
*/

class Socket
{
public:
    Socket();
    virtual ~Socket();
    BOOL CreateSocket();
    BOOL BindSocket(const UINT uiPort);
    BOOL ListenSocket()const;
    BOOL AcceptSocket(Socket & in_skt)const;
    BOOL ConnectSocket(std::string host, const UINT uiPort);
    VOID CloseSocket();
    INT SetSocketNoblocking(BOOL no);
    INT Send(const std::string &str)const;
    INT Recv(std::string &str)const;
    
    BOOL Is_Valid()const
    {
        return sockfd != -1;
    }
    

private:
    int sockfd;
    struct sockaddr_in sock_addr;
};


#endif
#include "e_socket.h"


/**************************************************************************
*				|
* Function Name : Socket.Socket
* Input			: 
* Author		: lily
* Date			: 2018-8-26
* Description	: 
* Return		: 
*				|
**************************************************************************/
Socket::Socket()
{
    memset(&sock_addr, 0, sizeof(sock_addr));
}

/**************************************************************************
*				|
* Function Name : Socket.~Socket
* Input			: 
* Author		: lily
* Date			: 2018-8-26
* Description	: 
* Return		: 
*				|
**************************************************************************/
Socket::~Socket()
{
    if (!Is_Valid())
    {
        CloseSocket();
    }
}


/**************************************************************************
*				|
* Function Name : Socket.CreateSocket
* Input			: 
* Author		: lily
* Date			: 2018-8-26
* Description	: 
* Return		: 
*				|
**************************************************************************/
BOOL Socket:: CreateSocket()
{
    INT iRet = 0;
    INT sockoptval = 1;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);

    if (!Is_Valid())
    {
        return false;
    }

    /* set reuse addr */
    iRet = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockoptval, sizeof(sockoptval));
    if (-1 == iRet)
    {
        return false;
    }

    return true;
}

/**************************************************************************
*				|
* Function Name : Socket.BindSocket
* Input			: 
* Author		: lily
* Date			: 2018-8-26
* Description	: 
* Return		: 
*				|
**************************************************************************/
BOOL Socket::BindSocket(const UINT uiPort)
{
    INT iRet = 0;
    
    if (!Is_Valid())
    {
        return false;
    }

    
    sock_addr.sin_family = AF_INET;
    sock_addr.sin_addr.s_addr = INADDR_ANY;
    sock_addr.sin_port = htons ( uiPort );

    //inet_pton(AF_INET, pHost, &(sock_addr.sin_addr);

    cout<<"server bind socket ..."<sockfd, (struct sockaddr *)&this->sock_addr,
                                                    (socklen_t *)&addr_len);
    if (!in_skt.Is_Valid())
    {
        return false;
    }

    return true;
}


/**************************************************************************
*				|
* Function Name : Socket.ConnectSocket
* Input			: 
* Author		: lily
* Date			: 2018-8-26
* Description	: 
* Return		: 
*				|
**************************************************************************/
BOOL Socket::ConnectSocket(std::string host, const UINT uiPort)
{
    INT iRet = 0;
    
    if (!Is_Valid())
    {
        return false;
    }

    sock_addr.sin_family = AF_INET;
    //sock_addr.sin_port = htonl(uiPort);
    /*
    inet_pton进行相反的转换,从数值格式(addrptr)转换到表达格式(strptr)。
    函数尝试转换由strptr指针所指的字符串,并通过addrptr指针存放二进制结果。若成功则返回1,
    否则如果对所指定的family而言输入的字符串不是有效的表达式,那么值为0。
    返回:1——成功,0----输入不是有效的表达式,-1——出错;

    inet_ntop进行相反的转换,从数值格式(addrptr)转换到表达格式(strptr)。
    len参数是目标存储单元的大小,以免该函数溢出其调用者的缓冲区。
    返回:指向结果的指针——成功,NULL——出错;
    */

    cout<<"host.c_str"< iRcvLen)
    {
        cout<<"recv error "<

Server端继承Socket类

// Definition of the ServerSocket class

#ifndef ServerSocket_class
#define ServerSocket_class

#include "e_socket.h"


class ServerSocket : private Socket
{
 public:

  ServerSocket ( UINT port );
  ServerSocket (){};
  virtual ~ServerSocket();

  const ServerSocket& operator << ( const std::string& ) const;
  const ServerSocket& operator >> ( std::string& ) const;

  void Accept ( ServerSocket& );

};


#endif


// Definition of the ServerSocket class

#include "e_server.h"
#include "SocketException.h"

ServerSocket::ServerSocket(UINT uiPort)
{
    BOOL bRes = false;

    bRes = Socket::CreateSocket();
    if (false == bRes)
    {
        throw SocketException ( "Could not create server socket." );
    }

    bRes = Socket::BindSocket(uiPort);
    if (false == bRes)
    {
        throw SocketException ( "Server Could not bind to port." );
    }

    bRes = Socket::ListenSocket();
    if(false == bRes)
    {
        throw SocketException ( "Could not listen to socket." );
    }
}

ServerSocket::~ServerSocket()
{
}


/**************************************************************************
*				|
* Function Name : ServerSocket.Accept
* Input			: 
* Author		: lily
* Date			: 2018-8-26
* Description	: 
* Return		: 
*				|
**************************************************************************/
void ServerSocket::Accept(ServerSocket &ser_skt)
{
    cout<<"accept connect..."<> ( std::string& str ) const
{
  if (! Socket::Recv(str))
    {
      throw SocketException ( "Could not read from socket." );
    }

  return *this;
}



Client 端继承Socket类

// Definition of the ClientSocket class

#ifndef ClientSocket_class
#define ClientSocket_class

#include "e_socket.h"


class ClientSocket : private Socket
{
 public:

  ClientSocket ( std::string host, UINT port );
  virtual ~ClientSocket(){};

  const ClientSocket& operator << ( const std::string& ) const;
  const ClientSocket& operator >> ( std::string& ) const;

};


#endif


// Implementation of the ClientSocket class

#include "e_client.h"
#include "SocketException.h"


ClientSocket::ClientSocket ( std::string host, UINT port )
{
  if ( ! Socket::CreateSocket() )
    {
      throw SocketException ( "Could not create client socket." );
    }

  if ( ! Socket::ConnectSocket(host, port))
    {
      throw SocketException ( "Could not connect to server." );
    }

}


const ClientSocket& ClientSocket::operator << ( const std::string& s ) const
{
  if ( ! Socket::Send(s) )
    {
      throw SocketException ( "Could not write to socket." );
    }

  return *this;

}


const ClientSocket& ClientSocket::operator >> ( std::string& s ) const
{
  if ( ! Socket::Recv(s) )
    {
      throw SocketException ( "Could not read from socket." );
    }

  return *this;
}


服务器主函数部分 :

#include "SocketException.h"
#include "e_server.h"


int main ( int argc, char *argv[] )
{
  std::cout << "running....\n";

  try
    {
      // Create the socket
      ServerSocket server ( 30000 );

      while ( true )
    	{

    	  ServerSocket new_sock;
    	  server.Accept(new_sock);

    	  try
    	    {
    	        while ( true )
        		{
        		  std::string data;
        		  new_sock >> data;/* operator << */
        		  new_sock << data;/* operator >> */
        		}
    	    }
    	  catch ( SocketException& ) 
    	  {
    	  }

    	}
    }
    catch ( SocketException& e )
    {
      std::cout << "Exception was caught:" << e.description() << "\nExiting.\n";
    }

  return 0;
}



客户端主函数部分:


#include "e_client.h"
#include "SocketException.h"
#include 
#include 

int main ( int argc, char *argv[] )
{
  try
    {

      ClientSocket client_socket ( "127.0.0.1", 30000 );

      std::string reply;

        try
    	{
    	  client_socket << "Test message.";
    	  client_socket >> reply;
    	}
        catch ( SocketException& ) {}

      std::cout << "We received this response from the server:\n\"" << reply << "\"\n";;

    }
  catch ( SocketException& e )
    {
      std::cout << "Exception was caught:" << e.description() << "\n";
    }

  return 0;
}


异常处理类

// SocketException class


#ifndef SocketException_class
#define SocketException_class

#include 

class SocketException
{
 public:
  SocketException ( std::string s ) : m_s ( s ) {};
  ~SocketException (){};

  std::string description() { return m_s; }

 private:

  std::string m_s;

};

#endif

效果:

客户端

li@li:~/C++/socket/client$ ./a.out 
host.c_str127.0.0.1
inet_pton
connect server... host = 127.0.0.1 port = 30000
We received this response from the server:
"Test message."
 

服务器:

li@li:~/C++/socket/server$ ./a.out 
running....
server bind socket ...
listening ...
accept connect...
remote socket closed
 

后续会在此基础上改进,并新增EPOLL类,丰富服务器处理类型

你可能感兴趣的:(C++)