客户端到服务器发送字符串消息c ++

时间:2015-11-10 01:12:38

标签: c++ sockets server client

我有一个服务器和一个客户端,我正在尝试将一条消息从客户端发送到服务器作为字符串。我成功完成了一次,但当我尝试发送另一个字符串时,我收到错误: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 - 向服务器发送命令 退出 - 退出计划

如果键入“server”,则以下选项为:

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

m - 向服务器发送消息

server.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

1 个答案:

答案 0 :(得分:0)

您的客户端代码显示错误 - 您在while(true)循环中调用connect()而不需要它 - 一旦您的客户端连接,它就不需要再次连接,直到连接终止并且插座已关闭。