【问题标题】:C send function between server and client not workingC服务器和客户端之间的发送功能不起作用
【发布时间】:2015-07-05 03:42:54
【问题描述】:

我正在尝试让服务器 (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, '\0', 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, '\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 ----*/
  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 到达接收时,它将继续并继续,一切似乎都很好。但是,我需要能够在 SENSORSERVER 运行时一次又一次地调用 CGI,并让服务器向客户端发送消息。它只发送一次!

第一轮循环输出 -

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

第二轮循环 -

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

谁能看出问题出在哪里?

【问题讨论】:

    标签: c multithreading tcp send


    【解决方案1】:

    问题是您的服务器只接受单个连接(单个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);
    

    如果您想对传入连接执行更复杂的操作,您可能希望派生一个进程或线程来处理它,而不是直接在循环中执行,因为在第一个连接完成之前无法接受第二个连接处理完毕,循环返回到accept调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-03
      • 2022-06-24
      • 1970-01-01
      • 2021-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多