Серверный сокет не получает сообщение в первый раз. Почему это происходит? - PullRequest
0 голосов
/ 15 января 2020

Я попал в странную ситуацию. Я создаю простой эхо-клиент-сервер. Клиент может отправить сообщение на сервер. Вызов accept успешно выполняется на сервере, но по какой-то причине он не обнаруживает клиентское сообщение в первый раз. Но когда клиент отправляет сообщение во второй раз, сервер может обнаружить сообщение и распечатать его.

Вот фрагмент сервера, на котором я принимаю соединение клиента.

while(1) {
    // continuously listen for the new client-requests
    int client_fd = accept(server_fd, (struct sockaddr*)&client,&client_socklen);
    if(client_fd > 0) {
     char b[10];
     while(1) {

      ssize_t response = recv(client_fd,b, 10, 0);
      if(response == 0) {printf("reached end of stream"); break;}
      if(response == -1) {printf("error"); break;}

     }

     fprintf("%s", b);

    }
}

Когда клиент отправляет запрос в первый раз, вызов на accept завершается успешно, и элемент управления входит в блок if, но там он не получает сообщение и просто печатает reached end of stream. Но когда клиент снова отправляет сообщение, он получает сообщение и печатает его. Почему это происходит? Клиент отправляет простое echo! сообщение.

Фрагмент клиента:

    #include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>
#include <strings.h>
#include <stdlib.h>
#include <unistd.h>

#define SERVER_ADDR "localhost"
#define SERVER_PORT 8889


int main(int argc, char **argv) {

    int socket_fd = 0;
    struct sockaddr_in server_socket_addr;

    // Converts localhost into 0.0.0.0
    struct hostent *he = gethostbyname(SERVER_ADDR);
    unsigned long server_addr_nbo = *(unsigned long *)(he->h_addr_list[0]);

    // Create socket (IPv4, stream-based, protocol likely set to TCP)
    if (0 > (socket_fd = socket(AF_INET, SOCK_STREAM, 0))) {
        fprintf(stderr, "client failed to create socket\n");
        exit(1);
    }

    bzero(&server_socket_addr, sizeof(server_socket_addr));
    server_socket_addr.sin_family = AF_INET;
    server_socket_addr.sin_port = htons(SERVER_PORT);
    server_socket_addr.sin_addr.s_addr = server_addr_nbo;

    // Connect socket to server
    if (0 > connect(socket_fd, (struct sockaddr *)&server_socket_addr, sizeof(server_socket_addr))) {
        fprintf(stderr, "client failed to connect to %s:%d!\n", SERVER_ADDR, SERVER_PORT);
        close(socket_fd);
        //          exit(1);
    } else {
        fprintf(stdout, "client connected to to %s:%d!\n", SERVER_ADDR, SERVER_PORT);
        char *my_message = "hey!!"
        int bytes_sent = send(socket_fd, my_message, strlen(my_message), 0);
    }

    // Close the socket and return
    close(socket_fd);
    return 0;
}

1 Ответ

1 голос
/ 15 января 2020

Вместо этого:

if(client_fd > 0) {
     char b[10];
     while(1) {

      ssize_t response = recv(client_fd,b, 10, 0);
      if(response == 0) {printf("reached end of stream"); break;}
      if(response == -1) {printf("error"); break;}

     }

     fprintf("%s", b);

Это:

if(client_fd > 0) {
     const size_t BUFFER_SIZE = 10;
     char b[BUFFER_SIZE+1];  // +1 for null termination
     while(1) {
      b[0] = '\0';
      ssize_t response = recv(client_fd,b, BUFFER_SIZE, 0);
      if(response == 0) {printf("reached end of stream"); break;}
      if(response == -1) {printf("error"); break;}
      b[response] = '\0';
      printf("%s\n", b);  //  \n so that the message will flush to the console
     }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...