服务器和客户端之间的C发送功能不起作用

C send function between server and client not working

我正在尝试让服务器 (SENSORSERVER) 和客户端 (CGI) 使用 send() 函数进行通信。 SENSORSERVER 的第一个循环将字符串 "Hello world" 正确地发送到 CGI,但是在 while 循环的第二个循环中,CGI 在 recv 函数上没有正确接收。

传感器服务器代码

int main() {

  pthread_mutex_init(&mutex, NULL);

  int welcomeSocket, newSocket;
  char buffer[1024];
  struct sockaddr_in serverAddr;
  struct sockaddr_storage serverStorage;
  socklen_t addr_size;

  //pthread_create(&t0, NULL ,background(),(void *)"");
  //pthread_detach(t0);

    //int pthread_join();
    pid = fork();

    if(pid == -1){
        printf("failed to fork");
    }

    if(pid == 0){

        pthread_create(&t0, NULL,  background(), (void*)"");
        pthread_detach(t0);

    } else {


          /*---- Create the socket. The three arguments are: ----*/
          /* 1) Internet domain 2) Stream socket 3) Default protocol (TCP in this case) */
          while(1){

          welcomeSocket = socket(PF_INET, SOCK_STREAM, 0);

          /*---- Configure settings of the server address struct ----*/
          /* Address family = Internet */
          serverAddr.sin_family = AF_INET;
          /* Set port number, using htons function to use proper byte order */
          serverAddr.sin_port = htons(7891);
          /* Set IP address to localhost */
          serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
          /* Set all bits of the padding field to 0 */
          memset(serverAddr.sin_zero, '[=10=]', sizeof serverAddr.sin_zero);



          /*---- Bind the address struct to the socket ----*/
          bind(welcomeSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));

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



          /*---- Accept call creates a new socket for the incoming connection ----*/
          addr_size = sizeof serverStorage;
          newSocket = accept(welcomeSocket, (struct sockaddr *) &serverStorage, &addr_size);

          /*---- Send message to the socket of the incoming connection ----*/

          int er = pthread_mutex_trylock(&mutex);


          if (er == 0)
          {




            strcpy(buffer,"Hello World\n");



            send(newSocket, buffer, sizeof(buffer), 0);


                close(newSocket);
                close(welcomeSocket);


              pthread_mutex_unlock(&mutex);


          }


    }
  }
return EXIT_SUCCESS;
}

和CGI客户端代码

char buf[1024];
char buf2[2024];




int main(void) {

  int clientSocket;
  char buffer[1024];
  struct sockaddr_in serverAddr;
  socklen_t addr_size;

  /*---- Create the socket. The three arguments are: ----*/
  /* 1) Internet domain 2) Stream socket 3) Default protocol (TCP in this case) */
  clientSocket = socket(PF_INET, SOCK_STREAM, 0);
  /*---- Configure settings of the server address struct ----*/
  /* Address family = Internet */
  serverAddr.sin_family = AF_INET;
  /* Set port number, using htons function to use proper byte order */
  serverAddr.sin_port = htons(7891);
  /* Set IP address to localhost */
  serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
  /* Set all bits of the padding field to 0 */
  memset(serverAddr.sin_zero, '[=11=]', 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 ----*/
  int er;
  er = recv(clientSocket, buffer, sizeof(buffer), 0);



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



  puts("<p>Hello <b>CGI</b</p>");
  puts("</BODY>");
  puts("</HTML>");


  return EXIT_SUCCESS;
    }

SENSORSERVER 将到达 accept() 函数,然后当 CGI 到达接收时它将继续并继续,一切似乎都很好。但是,我需要 CGI 能够在 SENSORSERVER 为 运行 时一次又一次地被调用,并且服务器可以向客户端发送消息。它只发送一次!

第一次循环输出 -

Data received: Hello World
<p>Hello <b>CGI</b</p>
</BODY>
</HTML>
logout

第二轮循环 -

Data received: 
<p>Hello <b>CGI</b</p>
</BODY>
</HTML>
logout

谁能看出问题出在哪里?

问题是您的服务器只接受一个连接(单个 accept 调用),然后在发送消息后退出。因此第二个客户端 运行 将连接失败(没有人再监听套接字)并打印空白消息(因为您忽略了错误代码)。

如果您希望服务器能够处理多个连接,则需要循环调用 accept。你究竟想怎么做取决于你想如何处理连接。最简单的方法是发送消息,关闭已接受的连接,然后循环:

while (1) { /* infinite loop */
    /*---- Accept call creates a new socket for the incoming connection ----*/
    addr_size = sizeof serverStorage;
    newSocket = accept(welcomeSocket, (struct sockaddr *) &serverStorage, &addr_size);
    if (newSocket < 0) {
        perror("accept");
        break; }
    /*---- Send message to the socket of the incoming connection ----*/
    int er = pthread_mutex_trylock(&mutex);
    if (er == 0) {
        strcpy(buffer,"Hello World\n");
        send(newSocket, buffer, sizeof(buffer), 0);
        close(newSocket);
        pthread_mutex_unlock(&mutex);
    } else {
        /* mutex lock failed (busy?) -- need to do something */
        strcpy(buffer,"Error occurred\n");
        send(newSocket, buffer, sizeof(buffer), 0);
        close(newSocket);
    }
}
close(welcomeSocket);

如果你想对传入连接做任何更复杂的事情,你可能想分叉一个进程或线程来处理它,而不是直接在循环中做,因为第二个连接只有在第一个连接之后才能被接受一个已经被处理,循环returns到accept调用。