ошибка сегментации(создан дамп ядра) в recvfrom

#c #sockets #segmentation-fault #recvfrom

Вопрос:

Я писал простой код на языке Си для создания сокета lisening. Код выглядит следующим образом:

 #include lt;stdio.hgt; #include lt;string.hgt; #include lt;sys/socket.hgt; #include lt;netinet/ip.hgt;  void main() {  struct sockaddr_in server;  struct sockaddr_in client;  int clientlen;  char buf[1500];   int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);   memset((char *)amp;server, 0, sizeof(server));  server.sin_family = AF_INET;  server.sin_addr.s_addr = htonl(INADDR_ANY);  server.sin_port = htons(9090);   if(bind(sock, (struct sockaddr *) amp;server, sizeof(server)) lt; 0)  error("ERROR on binding");   while(1) {  bzero(buf, 1500);  recvfrom(sock, buf, 1500-1, 0, (struct sockaddr *) amp;client, amp;clientlen);  printf("%sn", buf);  printf("%d - %sn", client.sin_port, client.sin_addr.s_addr);  }  close(sock); }  

Код компилируется без проблем, но когда я подключаюсь к серверу с клиентом с помощью netcat:

 nc -u 10.0.2.4 9090  

и я отправляю какое-то сообщение, на сообщение отвечают, а затем я получаю ошибку. Кто-нибудь знает, почему у меня такое поведение? Спасибо.

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

1. clientlen должен быть инициализирован в len of client . В настоящее время он неинициализирован.

Ответ №1:

Здесь есть две основные проблемы. Во-первых, clientlen ожидается, что он будет содержать размер адресной структуры до recvfrom вызова, но он неинициализирован. Поэтому установите его следующим образом:

 int clientlen = sizeof(client);  

Во-вторых, вы используете %s для печати client.sin_addr.s_addr , но это поле не является строкой. Вы должны использовать inet_ntoa для преобразования a struct inaddr_t в строку:

 printf("%d - %sn", ntohs(client.sin_port), inet_ntoa(client.sin_addr));  

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

1. Проблема с clientlen решена, если я прокомментирую вторую распечатку, я не получу ошибки. Тем не менее, я получаю ошибки, если хочу распечатать порт и адрес клиента…