客户端随机连接到服务器

时间:2017-03-20 00:33:41

标签: c sockets tcp

我正在尝试编写一个简单的客户端/服务器程序,其中服务器首先连接到客户端,并向客户端发送消息。然后,客户端以大写形式将消息回送给服务器。

问题是,连接是随机的;有时客户端连接,有时它不连接。

编辑:当它没有连接时,我收到“地址已在使用中”错误。有没有办法在服务器端释放地址?

SERVER.C

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>

int main(){
  int welcomeSocket, newSocket, portNum, clientLen, nBytes;
  char buffer[1024];
  struct sockaddr_in serverAddr;
  struct sockaddr_storage serverStorage;
  socklen_t addr_size;
  int counter = 0;

  welcomeSocket = socket(PF_INET, SOCK_STREAM, 0);

  portNum = 7891;

  serverAddr.sin_family = AF_INET;
  serverAddr.sin_port = htons(portNum);
  serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
  memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);  

  bind(welcomeSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));

  /*---- Listen on the socket, with 5 max connection requests queued ----*/
  if(listen(welcomeSocket,5)==0)
    printf("Listening\n");
  else
    printf("Error\n");

  /*---- Accept call creates a new socket for the incoming connection ----*/
  addr_size = sizeof serverStorage;
  while(1){
      newSocket = accept(welcomeSocket, (struct sockaddr *) &serverStorage, &addr_size);
/*    counter ++ ;*/
/*    printf("client connected: %d\n",counter);*/
      /*fork a child process to handle the new connection*/
      if(!fork()){
          /*---- Send message to the socket of the incoming connection ----*/
          strcpy(buffer,"Hello World\n");
          send(newSocket,buffer,13,0);
          recv(newSocket,buffer,13,0);

          /*---- Print the received message ----*/
          printf("Data received: %s",buffer);
          close(newSocket);
          exit(0);
      }
      /*if parent, close the socket and go back to listening new requests*/
      else{
          close(newSocket);
      }       
  }

  return 0;
}

CLIENT.C

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <ctype.h>

int main(){
  int clientSocket, portNum, nBytes;
  char buffer[1024];
  struct sockaddr_in serverAddr;
  socklen_t addr_size;

  clientSocket = socket(PF_INET, SOCK_STREAM, 0);

  portNum = 7891;

  serverAddr.sin_family = AF_INET;
  serverAddr.sin_port = htons(portNum);
  serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
  memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);  

  /*---- Connect the socket to the server using the address struct ----*/
  addr_size = sizeof serverAddr;
  connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size);

  /*---- Read the message from the server into the buffer ----*/
  nBytes = recv(clientSocket, buffer, 1024, 0);

  /*---- Print the received message ----*/
  printf("Data received: %s",buffer);   

  for (int i=0;i<nBytes-1;i++){
     buffer[i] = toupper(buffer[i]);
  }

  send(clientSocket,buffer,nBytes,0);


  return 0;
}

1 个答案:

答案 0 :(得分:2)

已使用的&#34;地址&#34;当套接字已绑定到该端口时,在调用bind时发生错误。在侦听TCP套接字的情况下,由于旧的连接套接字尚未完全关闭而在重新启动程序时会发生这种情况。

绑定侦听套接字时,应设置SO_REUSEADDR套接字选项。这将允许您在这些情况下绑定TCP侦听套接字。

int option = 1;
if (setsockopt(welcomeSocket, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)) == -1) {
    perror("setsockopt for SO_REUSEADDR failed");
    exit(1);
}

此功能应在socket之后但在bind之前调用。