#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 ofclient
. В настоящее время он неинициализирован.
Ответ №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 решена, если я прокомментирую вторую распечатку, я не получу ошибки. Тем не менее, я получаю ошибки, если хочу распечатать порт и адрес клиента…