C++ 实现停止和等待ARQ

C++ 实现停止和等待ARQ,c++,sockets,C++,Sockets,我试图模仿这个协议。这就是我到目前为止所做的: 接收器端代码: // SocketException class #ifndef SocketException_class #define SocketException_class #include <string> class SocketException { public: SocketException ( std::string s ) : m_s ( s ) {}; ~SocketException (

我试图模仿这个协议。这就是我到目前为止所做的: 接收器端代码:

// SocketException class


#ifndef SocketException_class
#define SocketException_class

#include <string>

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

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

 private:

  std::string m_s;

};

#endif

// Definition of the Socket class

#ifndef Socket_class
    #define Socket_class


    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <unistd.h>
    #include <string>
    #include <arpa/inet.h>


    const int MAXHOSTNAME = 200;
    const int MAXCONNECTIONS = 5;
    const int MAXRECV = 500;

    class Socket
    {
     public:
      Socket();
      virtual ~Socket();

      // Server initialization
      bool create();
      bool bind ( const int port );
      bool listen() const;
      bool accept ( Socket& ) const;

      // Client initialization
      bool connect ( const std::string host, const int port );

      // Data Transimission
      bool send ( const std::string ) const;
      int recv ( std::string& ) const;


      void set_non_blocking ( const bool );

      bool is_valid() const { return m_sock != -1; }

     private:

      int m_sock;
      sockaddr_in m_addr;


    };


#endif

// Implementation of the Socket class.

#include "string.h"
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include<iostream>


Socket::Socket() :
  m_sock ( -1 )
{

  memset ( &m_addr,
       0,
       sizeof ( m_addr ) );

}

Socket::~Socket()
{
  if ( is_valid() )
    ::close ( m_sock );
}

bool Socket::create()
{
  m_sock = socket ( AF_INET,
            SOCK_STREAM,
            0 );

  if ( ! is_valid() )
    return false;


  // TIME_WAIT - argh
  int on = 1;
  if ( setsockopt ( m_sock, SOL_SOCKET, SO_REUSEADDR, ( const char* ) &on, sizeof ( on ) ) == -1 )
    return false;


  return true;

}



bool Socket::bind ( const int port )
{

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



  m_addr.sin_family = AF_INET;
  m_addr.sin_addr.s_addr = INADDR_ANY;
  m_addr.sin_port = htons ( port );

  int bind_return = ::bind ( m_sock,
                 ( struct sockaddr * ) &m_addr,
                 sizeof ( m_addr ) );


  if ( bind_return == -1 )
    {
      return false;
    }

  return true;
}


bool Socket::listen() const
{
  if ( ! is_valid() )
    {
      return false;
    }

  int listen_return = ::listen ( m_sock, MAXCONNECTIONS );


  if ( listen_return == -1 )
    {
      return false;
    }

  return true;
}


bool Socket::accept ( Socket& new_socket ) const
{
  int addr_length = sizeof ( m_addr );
  new_socket.m_sock = ::accept ( m_sock, ( sockaddr * ) &m_addr, ( socklen_t * ) &addr_length );

  if ( new_socket.m_sock <= 0 )
    return false;
  else
    return true;
}


bool Socket::send ( const std::string s ) const
{
  int status = ::send ( m_sock, s.c_str(), s.size(), MSG_NOSIGNAL );
  if ( status == -1 )
    {
      return false;
    }
  else
    {
      return true;
    }
}


int Socket::recv ( std::string& s ) const
{
  char buf [ MAXRECV + 1 ];

  s = "";

  memset ( buf, 0, MAXRECV + 1 );

  int status = ::recv ( m_sock, buf, MAXRECV, 0 );

  if ( status == -1 )
    {
      std::cout << "status == -1   errno == " << errno << "  in Socket::recv\n";
      return 0;
    }
  else if ( status == 0 )
    {
      return 0;
    }
  else
    {
      s = buf;
      return status;
    }
}



bool Socket::connect ( const std::string host, const int port )
{
  if ( ! is_valid() ) return false;

  m_addr.sin_family = AF_INET;
  m_addr.sin_port = htons ( port );

  int status = inet_pton ( AF_INET, host.c_str(), &m_addr.sin_addr );

  if ( errno == EAFNOSUPPORT ) return false;

  status = ::connect ( m_sock, ( sockaddr * ) &m_addr, sizeof ( m_addr ) );

  if ( status == 0 )
    return true;
  else
    return false;
}

void Socket::set_non_blocking ( const bool b )
{

  int opts;

  opts = fcntl ( m_sock,
         F_GETFL );

  if ( opts < 0 )
    {
      return;
    }

  if ( b )
    opts = ( opts | O_NONBLOCK );
  else
    opts = ( opts & ~O_NONBLOCK );

  fcntl ( m_sock,
      F_SETFL,opts );

}

// Definition of the ServerSocket class

#ifndef ServerSocket_class
    #define ServerSocket_class

    class ServerSocket : private Socket
    {
     public:

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

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

      void accept ( ServerSocket& );

    };
#endif

// Implementation of the ServerSocket class

ServerSocket::ServerSocket ( int port )
{
  if ( ! Socket::create() )
    {
      throw SocketException ( "Could not create server socket." );
    }

  if ( ! Socket::bind ( port ) )
    {
      throw SocketException ( "Could not bind to port." );
    }

  if ( ! Socket::listen() )
    {
      throw SocketException ( "Could not listen to socket." );
    }

}

ServerSocket::~ServerSocket()
{
}


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

  return *this;

}


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

  return *this;
}

void ServerSocket::accept ( ServerSocket& sock )
{
  if ( ! Socket::accept ( sock ) )
    {
      throw SocketException ( "Could not accept socket." );
    }
}

#include <string>

using namespace std;
int main ( int argc, int argv[] )
{
  cout << "Waiting to receive frames...\n";

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

      while ( true )
    {

      ServerSocket new_sock;
      server.accept ( new_sock );

      try
        {
            while ( true )
            {
              string data;
              cout<<"Recieving  data."; //not being displayed
              new_sock >> data;
              cout<<"Recieved data. Sending back the acknowledgment";
              new_sock << data;
            }
        }
      catch ( SocketException& ) {}

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

  return 0;
}
// SocketException class


#ifndef SocketException_class
#define SocketException_class

#include <string>

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

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

 private:

  std::string m_s;

};

#endif

// Definition of the Socket class

#ifndef Socket_class
    #define Socket_class


    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <unistd.h>
    #include <string>
    #include <arpa/inet.h>


    const int MAXHOSTNAME = 200;
    const int MAXCONNECTIONS = 5;
    const int MAXRECV = 500;

    class Socket
    {
     public:
      Socket();
      virtual ~Socket();

      // Server initialization
      bool create();
      bool bind ( const int port );
      bool listen() const;
      bool accept ( Socket& ) const;

      // Client initialization
      bool connect ( const std::string host, const int port );

      // Data Transimission
      bool send ( const std::string ) const;
      int recv ( std::string& ) const;


      void set_non_blocking ( const bool );

      bool is_valid() const { return m_sock != -1; }

     private:

      int m_sock;
      sockaddr_in m_addr;


    };


#endif

// Implementation of the Socket class.

#include "string.h"
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include<iostream>


Socket::Socket() :
  m_sock ( -1 )
{

  memset ( &m_addr,
       0,
       sizeof ( m_addr ) );

}

Socket::~Socket()
{
  if ( is_valid() )
    ::close ( m_sock );
}

bool Socket::create()
{
  m_sock = socket ( AF_INET,
            SOCK_STREAM,
            0 );

  if ( ! is_valid() )
    return false;


  // TIME_WAIT - argh
  int on = 1;
  if ( setsockopt ( m_sock, SOL_SOCKET, SO_REUSEADDR, ( const char* ) &on, sizeof ( on ) ) == -1 )
    return false;


  return true;

}



bool Socket::bind ( const int port )
{

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



  m_addr.sin_family = AF_INET;
  m_addr.sin_addr.s_addr = INADDR_ANY;
  m_addr.sin_port = htons ( port );

  int bind_return = ::bind ( m_sock,
                 ( struct sockaddr * ) &m_addr,
                 sizeof ( m_addr ) );


  if ( bind_return == -1 )
    {
      return false;
    }

  return true;
}


bool Socket::listen() const
{
  if ( ! is_valid() )
    {
      return false;
    }

  int listen_return = ::listen ( m_sock, MAXCONNECTIONS );


  if ( listen_return == -1 )
    {
      return false;
    }

  return true;
}


bool Socket::accept ( Socket& new_socket ) const
{
  int addr_length = sizeof ( m_addr );
  new_socket.m_sock = ::accept ( m_sock, ( sockaddr * ) &m_addr, ( socklen_t * ) &addr_length );

  if ( new_socket.m_sock <= 0 )
    return false;
  else
    return true;
}


bool Socket::send ( const std::string s ) const
{
  int status = ::send ( m_sock, s.c_str(), s.size(), MSG_NOSIGNAL );
  if ( status == -1 )
    {
      return false;
    }
  else
    {
      return true;
    }
}


int Socket::recv ( std::string& s ) const
{
  char buf [ MAXRECV + 1 ];

  s = "";

  memset ( buf, 0, MAXRECV + 1 );

  int status = ::recv ( m_sock, buf, MAXRECV, 0 );

  if ( status == -1 )
    {
      std::cout << "status == -1   errno == " << errno << "  in Socket::recv\n";
      return 0;
    }
  else if ( status == 0 )
    {
      return 0;
    }
  else
    {
      s = buf;
      return status;
    }
}



bool Socket::connect ( const std::string host, const int port )
{
  if ( ! is_valid() ) return false;

  m_addr.sin_family = AF_INET;
  m_addr.sin_port = htons ( port );

  int status = inet_pton ( AF_INET, host.c_str(), &m_addr.sin_addr );

  if ( errno == EAFNOSUPPORT ) return false;

  status = ::connect ( m_sock, ( sockaddr * ) &m_addr, sizeof ( m_addr ) );

  if ( status == 0 )
    return true;
  else
    return false;
}

void Socket::set_non_blocking ( const bool b )
{

  int opts;

  opts = fcntl ( m_sock,
         F_GETFL );

  if ( opts < 0 )
    {
      return;
    }

  if ( b )
    opts = ( opts | O_NONBLOCK );
  else
    opts = ( opts & ~O_NONBLOCK );

  fcntl ( m_sock,
      F_SETFL,opts );

}

// Definition of the ClientSocket class

#ifndef ClientSocket_class
    #define ClientSocket_class

    class ClientSocket : private Socket
    {
     public:

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

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

    };

#endif

// Implementation of the ClientSocket class



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

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

}


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 <iostream>
#include <string>
using namespace std;

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

      ClientSocket client_socket ( "localhost", 30000 );

      string reply, message;

      while(1){
          try{
              cout<<"Enter the frame to be sent: ";
              cin>>message;
              client_socket << message;
              client_socket >> reply;
          }
          catch ( SocketException& ) {}

          cout << "We received this response from the server:\n\"" << reply << "\"\n";
      }
    }
  catch ( SocketException& e )
    {
      cout << "Exception was caught:" << e.description() << "\n";
    }

  return 0;
}
//SocketException类
#ifndef SocketException_类
#定义SocketException_类
#包括
类SocketException
{
公众:
SocketException(std::string s):m_s(s){};
~SocketException(){};
std::string description(){return m_s;}
私人:
std::字符串m_s;
};
#恩迪夫
//套接字类的定义
#ifndef插座类
#定义套接字类
#包括
#包括
#包括
#包括
#包括
#包括
#包括
const int MAXHOSTNAME=200;
const int MAXCONNECTIONS=5;
常数int MAXRECV=500;
类套接字
{
公众:
套接字();
虚拟~Socket();
//服务器初始化
bool create();
布尔绑定(常量int端口);
bool listen()常量;
布尔接受(套接字和)常量;
//客户端初始化
bool connect(const std::string主机,const int端口);
//数据传输
bool send(const std::string)const;
int recv(std::string&)const;
无效集非阻塞(常数布尔);
bool is_valid()常量{return m_sock!=-1;}
私人:
int m_袜子;
m_addr中的sockaddr_;
};
#恩迪夫
//套接字类的实现。
#包括“string.h”
#包括
#包括
#包括
#包括
套接字::套接字():
m_短袜(-1)
{
memset和m_地址,
0,
sizeof(m_addr));
}
套接字::~Socket()
{
如果(u是否有效())
::关闭(m_sock);
}
bool套接字::create()
{
m_sock=插座(AF INET,
苏克河,
0 );
如果(!is_valid())
返回false;
//等待时间-啊
int on=1;
if(setsockopt(m_sock,SOL_SOCKET,SO_REUSEADDR,(const char*)&on,sizeof(on))=-1)
返回false;
返回true;
}
bool套接字::绑定(常量int端口)
{
如果(!is_valid())
{
返回false;
}
m_addr.sinu family=AF_INET;
m_addr.sin_addr.s_addr=INADDR_ANY;
m_addr.sin_port=htons(port);
int bind_return=::bind(m_sock,
(结构sockaddr*)和m_addr,
sizeof(m_addr));
if(bind_return==-1)
{
返回false;
}
返回true;
}
布尔套接字::listen()常量
{
如果(!is_valid())
{
返回false;
}
int listen\u return=::listen(m_sock,MAXCONNECTIONS);
if(listen\u return==-1)
{
返回false;
}
返回true;
}
bool Socket::accept(Socket和new_Socket)const
{
int addr_length=sizeof(m_addr);
new_socket.m_sock=:accept(m_sock,(sockaddr*)和m_addr,(socklen_t*)和addr_length);
if(新的m型插座)