Клиентский код не может считывать данные с сервера [сокеты]

#c #sockets

Вопрос:

Моя цель-реализовать простую передачу данных с сервера на клиент. Проблема в том, что клиент большую часть времени не может считывать данные с сервера (это работает только иногда), даже если сервер сообщает, что передача прошла успешно.

сервер.c

 #include lt;stdio.hgt; #include lt;stdlib.hgt; #include lt;string.hgt; #include lt;sys/socket.hgt; #include lt;netinet/in.hgt; #include lt;unistd.hgt;  #define PORT 8080  void main() {  int sock = socket(AF_INET, SOCK_STREAM, 0), option = 1;  struct sockaddr_in address;  socklen_t addrlen = sizeof(address);  char buffer[1024] = {0};  char source_file[] = "lt;pathgt;/something.txt";   char fname[] = "something.txt";   address.sin_family = AF_INET;  address.sin_addr.s_addr = INADDR_ANY;  address.sin_port = htons(PORT);   setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, amp;option, sizeof(option));   if(bind(sock, (struct sockaddr*) amp;address, sizeof(address)) == -1){  perror("Could not bind to address");  return;  }  if(listen(sock, 5) == -1) {  perror("Error while listening to connections");  return;  }  int new_socket = accept(sock, (struct sockaddr*) amp;address, amp;addrlen);    if(new_socket == -1){  perror("Error connecting to client");  exit(EXIT_FAILURE);  }  else printf("Connected to clientn");   // first send the filename  if(send(new_socket, fname, sizeof(fname), 0) == -1){  perror("Error while sending file");  return;  }  printf("Sending file %snn", source_file);  FILE* f = fopen(source_file, "r");   // send the contents of the file  while(fgets(buffer, sizeof(buffer), f)){  printf("Sending %s", buffer);  if(send(new_socket, buffer, strlen(buffer), 0) == -1)  perror("Error while sendingn");  else printf("Successfully sentnn");  memset(buffer, 0, sizeof(buffer));  }   printf("File transfer completen");  fclose(f); }  

клиент.c

 #include lt;stdio.hgt; #include lt;stdlib.hgt; #include lt;string.hgt; #include lt;sys/socket.hgt; #include lt;arpa/inet.hgt; #include lt;unistd.hgt;  #define PORT 8080  void main() {  int sock = socket(AF_INET, SOCK_STREAM, 0);  long val;  struct sockaddr_in address;  char buffer[1024] = {0};   address.sin_family = AF_INET;  address.sin_port = htons(PORT);   if(inet_pton(AF_INET, "127.0.0.1", amp;address.sin_addr) == -1){  perror("Invalid IP value");  exit(EXIT_FAILURE);  }  if(connect(sock,(struct sockaddr*) amp;address, sizeof(address)) == -1){  perror("Connection Error");  exit(EXIT_FAILURE);  }  else printf("Connected to servern");   // Get file name from server  if(read(sock, buffer, sizeof(buffer)) == -1){  perror("Could not read filename from server");  exit(EXIT_FAILURE);  }   printf("Receiving file %sn", buffer);  FILE *f = fopen(buffer, "w");  // printf("%ld", read(sock, buffer, sizeof(buffer)));   while((val = read(sock, buffer, sizeof(buffer)))){  if (val == 0) break;  if (val == -1) {  perror("Error reading the content");  break;  }  printf("Read returned %ldn", val);    printf("Received %s", buffer);  fputs(buffer, f);  memset(buffer, 0, sizeof(buffer));  }   printf("File transfer completen");  fclose(f); }  

Sample text file for data transfer

 Hello there! Nice to meet you. This is a text file. Bye Bye :) Have a good day.  

Выполнение со стороны сервера

 $ cc ./server.c -o server $ ./server Connected to client Sending file /home/username/Documents/something.txt  Sending Hello there! Successfully sent  Sending Nice to meet you. Successfully sent  Sending This is a text file. Successfully sent  Sending Bye Bye :) Successfully sent  Sending Have a good day. Successfully sent  File transfer complete  

Это был вывод, который я получил со стороны сервера. Это странно, потому что на стороне клиента я не получил никакого сообщения

 $ cc ./client.c -o client $ ./client Connected to server Receiving file something.txt File transfer complete  

Цикл while на стороне клиента вообще не выполнялся (поскольку данные в буфере не печатались), а функция чтения не возвращала -1, иначе было бы отображено правильное сообщение.

Этот точный клиентский код работает только иногда, а иногда нет. В чем здесь проблема?

Комментарии:

1. send(new_socket, buffer, strlen(buffer), 0) отправляет строку без нулевого терминатора.

2. read(sock, buffer, sizeof(buffer)) не проверяет, сколько байтов он получил. Обратите внимание, что данные recv не обязательно соответствуют границам отправки.

3. такого рода заявление также должно быть у клиента: setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, amp;option, sizeof(option));

4. относительно: printf("Read returned %ldn", val); поскольку это сообщение не было выведено, этот вызов: while((val = read(sock, buffer, sizeof(buffer)))){ вернул 0