【问题标题】:Client to Server sending string message c++客户端到服务器发送字符串消息c ++
【发布时间】:2015-11-10 01:12:38
【问题描述】:

我有一个服务器和一个客户端,我正在尝试将消息从客户端作为字符串发送到服务器。我成功地做了一次,但是当我尝试发送另一个字符串时,我得到了错误:client: connect error :Transport endpoint is already connected

-----如何编译-----

    g++ server.cpp -std=c++11 -o server.x -lpthread
    g++ client.cpp -std=c++11 -o client.x

-----如何执行-----

    ./server.x
    ./client.x <IP Address>

两个文件都执行后,会出现以下选项:

--------- 选项 ----------

server - 向服务器发送命令 exit - 退出程序

如果您键入“服务器”,以下选项将是:

-----服务器命令选项:-----

m - 向服务器发送消息

服务器.cpp

int main()  {
  int sockid, newsd;
  struct sockaddr_in my_addr, client_addr;
  socklen_t clilen = sizeof(client_addr);
  thread cmd;

  cout << "Server creating socket.\n";
  if( (sockid = socket(AF_INET,SOCK_STREAM,0)) < 0) {
    cout << "Socket Error.\n";
    exit(0);
  }

  cout << "Server binding my local socket.\n";
  bzero((char *) &my_addr,sizeof(my_addr));
  my_addr.sin_family = AF_INET;
  my_addr.sin_port = htons(MY_PORT_ID);
  my_addr.sin_addr.s_addr = htons(INADDR_ANY);
  if( bind(sockid ,(struct sockaddr *) &my_addr,sizeof(my_addr)) < 0 ) {
    cout <<  "Bind error.\n";
    exit(0);
  }
  cout << "Server starting listen.\n";
  if( listen(sockid,5) < 0 ) {
    cout << "Listen error.\n";
    exit(0);
  }
  cout << "Server running...listening for connections.\n";

    for( ; ; ) {
    cout << "Server starting accept.\n";

    cout << "newd: " << newsd << endl;
    cout << "sockid: " << sockid << endl;
    cout << "client_addr: " << &client_addr << endl;
    cout << "clilen: " << clilen << endl;

    if ((newsd = accept(sockid ,(struct sockaddr *) &client_addr, &clilen)) < 0) {
      perror( "Failed to accept." );
      exit(0);
    }
    cout << "newsd: " << newsd << endl;
    cout << "Server return from accept, socket for this ftp: "<< newsd << endl;

    //    close(sockid);   /* child shouldn't do an accept */

    thread cmd ( receiveCommand, newsd );
    //cmd.detach();
    //cmd.join();

    //    close (newsd);
    //    exit(0);         /* child all done with work */
  }
  //  cmd.join();
  /* Parent continues below here */
  close(newsd);    /* parent all done with client, only child */
  close(sockid);
  return 0;

}

void receiveCommand(int newsd)
{
  string cmd;
  int msg_ok,fail,req,tmp;
  char command[MAXLINE], commandSize = 0;

  req = 0;
  if((readn(newsd,(char *)&req,sizeof(req))) < 0) {
    perror( "Read error" );
    exit(0);
  }

  req = ntohs(req);
  cout << "Client request code is: " << req << endl;
  if (req!=REQUESTCOMMAND) {
    cout << "Unsupported operation. goodbye\n";
    /* reply to client: command not OK  (code: 150) */
    msg_ok = COMMANDNOTSUPPORTED;
    msg_ok = htons(msg_ok);

    if((writen(newsd,(char *)&msg_ok,sizeof(msg_ok))) < 0 ) {
      perror( "Write error." );
      exit(0);
    }
    exit(0);
  }

  /* reply to client: command OK  (code: 160) */
  msg_ok = COMMANDSUPPORTED;
  msg_ok = htons(msg_ok);
  if( writen(newsd,(char *)&msg_ok,sizeof(msg_ok))  < 0 ) {
    perror( "Write error.");
    exit(0);
  }

  fail = COMMANDOK;
  if( (commandSize = read(newsd,command,MAXLINE)) < 0 ) {
    perror("Command read error." );
    fail = BADCOMMAND ;
  }
  command[commandSize] = '\0';
  tmp = htons(fail);
  if( (writen(newsd,(char *)&tmp,sizeof(tmp))) < 0 ) {
    perror("Write error" );
    exit(0);
  }
  if(fail == BADCOMMAND) {
    cout << "Server cant do command.\n";
    close(newsd);
    exit(0);
  }
  cout << "Command is: " << command << endl;

  if( command == "gbye"){
    cout << endl;
    cout << "Client requested server to shutdown...\n";
    cout << "Goodbye.\n";
    exit( 0 );
  }
  else{
    cout << "Command TRANSFER COMPLETE on socket " << newsd << endl;
  }
  close(newsd);
}

/*
  To take care of the possibility of buffer limmits in the kernel for the
  socket being reached (which may cause read or write to return fewer characters
  than requested), we use the following two functions */

int readn(int sd,char *ptr,int size)
{
  int no_left,no_read;
  no_left = size;
  while (no_left > 0) {
    no_read = read(sd,ptr,no_left);
    if(no_read <0)  return(no_read);
    if (no_read == 0) break;
    no_left -= no_read;
    ptr += no_read;
  }
  return(size - no_left);
}

int writen(int sd,char *ptr,int size)
{         int no_left,no_written;
  no_left = size;
  while (no_left > 0) {
    no_written = write(sd,ptr,no_left);
    if(no_written <=0)  return(no_written);
    no_left -= no_written;
    ptr += no_written;
  }
  return(size - no_left);
}

client.cpp

int main(int argc,char *argv[])
{
  int sockid, newsd, portNum, clientportNum, serverportNum;
  struct sockaddr_in my_addr, server_addr;

  if( argc != 2 ) {
    cout << "Error: Usage : IP-dotted-notation \n", argv[0];
    exit(0);
  }

  if( (sockid = socket(AF_INET,SOCK_STREAM,0)) < 0 )  {
    cout << "Client Socket Error.\n";
    exit(0);
  }

  clientportNum = 8000;
  serverportNum = 8001;

  cout << "Client Binding My Local Socket\n";
  bzero((char *) &my_addr, sizeof(my_addr));
  my_addr.sin_family = AF_INET;
  my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  my_addr.sin_port = htons(clientportNum);

  if( bind(sockid ,(struct sockaddr *) &my_addr,sizeof(my_addr)) < 0 ){
    cout << "Client Bind Error.\n";
    exit(0);
  }

  cout << "Client Starting Connect\n";
  bzero((char *) &server_addr,sizeof(server_addr));
  server_addr.sin_family = AF_INET;
  server_addr.sin_addr.s_addr = inet_addr(argv[1]);
  server_addr.sin_port = htons(serverportNum);

  while( 1 ){
      string cmd_option;
      cout << endl;
      cout << "---------- Options ----------\n";
      cout << "server - send a command to the server\n";
      cout << "exit   - exit program\n";
      cout << endl;

      cout << "~: ";
      getline(cin, cmd_option);

      if( cmd_option == "server" ){
        // *****Error Here*****
        if( connect(sockid ,(struct sockaddr *) &server_addr, sizeof(server_addr)) < 0 ) {
          //cout << "Client Connect Error.\n";
          printf("client: connect  error :%s\n",  strerror( errno ));
          exit(0);
        }
        giveServerCommand(sockid);
      }
      else if( cmd_option == "exit" ){
        cout << endl;
        cout << "Exiting program...\n";
        cout << "Goodbye.\n";
        exit(0);
      }
      else{
        cout << "Invalid Command.\n";
      }
    }
}
void giveServerCommand(int sockid)
{

    string user_input;

    // User Interface
    cout << "\n-----Server Command Options:-----\n";
    cout << "m      -   send message to server\n";

    cout << "\n";

    cout << "~: ";
    getline(cin, user_input);

    if ( user_input == "m" ){

      string buffer;
      cout << "\nType a command to the server: ";
      getline( cin, buffer );
      cout << "You typed: " << buffer << endl;

      int getcommand,msg,msg_2,len;
      len = buffer.size();

      getcommand = htons(REQUESTCOMMAND);
      cout << "Client sending command request to server.\n";

      int n = 0;
      if( n = (writen(sockid,(char *)&getcommand,sizeof(getcommand))) < 0 ) {
        cout << "Client write error: " << n << endl;
        exit(0);
      }

      /* want for go-ahead from server */
      cout << "command: " << getcommand << endl;
      cout << "sockid: " << sockid << endl;
      cout << "msg: " << &msg << endl;
      cout << "msg size: " << sizeof(msg) << endl;

      msg = 0;
      if((readn(sockid,(char *)&msg,sizeof(msg)))< 0) {
        cout << "Client read error.\n";
        exit(0);
      }
      cout << "msg: " << msg << endl;
      msg = ntohs(msg);
      cout << "msg after ntohs: " << msg << endl;
      if (msg==COMMANDNOTSUPPORTED) {
        cout << "Server refused command. Goodbye...\n";
        cout << endl;
        exit(0);
      }
      else
        cout << "Server replied, command supported.\n";

      /* send command to server */
      cout << "Client sending command.\n";

      cout << "sockid: " << sockid << endl;
      cout << "buffer: " << buffer.c_str() << endl;
      cout << "len: " << len << endl;

      if ((writen(sockid, (char *) buffer.c_str(),len)) < 0) {
        cout << "Client write error.\n";
        exit(0);
      }
      /* see if server replied that command is OK */
      cout << "sockid: " << sockid << endl;
      cout << "msg2: " << &msg_2 << endl;
      cout << "msg2 size: " << sizeof(msg_2) << endl;

      msg_2 = 0;
      if (readn(sockid, (char *)&msg_2, sizeof(msg_2)) < 0) {
        cout << "Client read error: %s\n",  strerror( errno );
        exit(0);
      }

      cout << "msg2 before ntohs: " << msg_2 << endl;
      msg_2 = ntohs(msg_2);
      cout << "msg2 after ntohs: " << msg_2 << endl;

      if (msg_2 == BADCOMMAND) {
        cout << "Server reported bad command. Goodbye...\n";
        exit(0);
      }
      else
        cout << "Server replied, Command OK.\n";

      /*Command transfer ends. client terminates after closing all its sockets*/
      cout << "COMMAND TRANSFER COMPLETE\n";
    }
    else{
      cout << "\nInvalid Option.\n";
    }
}

int readn(int sd, char *ptr, int size)
{

  int no_left,no_read;

  cout << "-----Within readn function------" << endl;
  cout << "sd: " << sd << endl;
  cout << "char ptr: " << &ptr << endl;
  cout << "size: " << size << endl;

  no_left = size;
  while (no_left > 0) {
    no_read = read(sd,ptr,no_left);
    cout << "no_read: " << no_read << endl;
    if(no_read <0)  return(no_read);
    if (no_read == 0) break;
    no_left -= no_read;
    ptr += no_read;
  }
  cout << "size - no_left: " << size - no_left << endl;
  cout << "--------------------------------" << endl;
  return(size - no_left);
}

int writen(int sd,char *ptr,int size)
{
  /*
  cout << "-----Within writen function------" << endl;
  cout << "sd: " << sd << endl;
  cout << "char ptr: " << &ptr << endl;
  cout << "size: " << size << endl;
  */
  int no_left,no_written;
  no_left = size;
  while (no_left > 0) {
    no_written = write(sd,ptr,no_left);
    //cout << "no_written: " << no_written << endl;
    if(no_written <=0)  return(no_written);
    no_left -= no_written;
    ptr += no_written;
  }
  /*
  cout << "size - no_left: " << size - no_left << endl;
  cout << "--------------------------------" << endl;
  */
  return(size - no_left);
}

错误:client: connect error :Transport endpoint is already connected

【问题讨论】:

  • 您是否在同一台机器上同时运行多个客户端或服务器?
  • 同一台机器上只有一个客户端和一个服务器@NathanTuggy
  • 没有必要在连接之前绑定客户端套接字,这可能是个坏主意。

标签: c++ sockets server client


【解决方案1】:

您的客户端代码出现错误 - 您在 while(true) 循环中调用 connect() 而不需要它 - 一旦您的客户端连接,它不需要再次这样做,直到连接终止后并且套接字已关闭。

【讨论】:

    猜你喜欢
    • 2016-09-11
    • 1970-01-01
    • 2013-04-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-02
    • 2015-01-05
    • 2017-03-08
    相关资源
    最近更新 更多