У меня возникла проблема с сегментацией при написании проекта клиент-сервер в UDP. Это происходит на стороне сервера, когда я получаю пакет от клиента и отправляю ACK обратно. Я попытался найти решения и получил UDP Server giving Segmentation Fault и C concurrent UDP socket , weird segmentation fault, но, похоже, оба из них не являются ответом, который я ищу.Ошибка сегментации в UDP
Вот мой код
#include <ctype.h> /* for toupper */
#include <stdio.h> /* for standard I/O functions */
#include <stdlib.h> /* for exit */
#include <string.h> /* for memset */
#include <sys/socket.h> /* for socket, sendto, and recvfrom */
#include <netinet/in.h> /* for sockaddr_in */
#include <unistd.h> /* for close */
#define STRING_SIZE 1024
#define SERV_UDP_PORT 12311
int main(void) {
int sock_server;
struct sockaddr_in server_addr;
unsigned short server_port;
struct sockaddr_in client_addr;
unsigned int client_addr_len;
char sentence[STRING_SIZE];
char modifiedSentence[STRING_SIZE];
unsigned int msg_len;
int bytes_sent, bytes_recd;
unsigned int i;
struct Pkt
{
short length;
short seqnum;
char databytes[80];
};
struct Pkt* pkt;
int j ; //for loop
int seq;
short num_of_bytes;
//char ack_num[2];
struct Ack
{
short ack_num;
};
struct Ack* ack;
/* open a socket */
if ((sock_server = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
perror("Server: can't open datagram socket\n");
exit(1);
}
/* initialize server address information */
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl (INADDR_ANY);
server_port = SERV_UDP_PORT;
server_addr.sin_port = htons(server_port);
/* bind the socket to the local server port */
if (bind(sock_server, (struct sockaddr *) &server_addr,
sizeof (server_addr)) < 0) {
perror("Server: can't bind to local address\n");
close(sock_server);
exit(1);
}
/* wait for incoming messages in an indefinite loop */
printf("Waiting for incoming messages on port %hu\n\n",
server_port);
client_addr_len = sizeof (client_addr);
for (;;) {
bytes_recd = recvfrom(sock_server, pkt, sizeof(*pkt), 0, (struct sockaddr *) &client_addr, &client_addr_len);
ack->ack_num = pkt->seqnum;
printf("%02d\n", ack->ack_num);
num_of_bytes = pkt->length;
printf("The sequence number is: %d\n", ack->ack_num);
printf("Received Sentence is: %s\n with length %d\n\n", pkt->databytes, num_of_bytes);
msg_len = 3;
/* send message */
bytes_sent = sendto(sock_server, (struct Ack*)&ack, msg_len, 0, (struct sockaddr*) &client_addr, client_addr_len); //Here is the segmentation fault comes from
}
}
стороне сервера я не очень хорошо на C, так что простите меня, если код глупо. Просьба указать на что-то неправильное или просто выглядит странно. Заранее благодарим за любую помощь.
Спасибо, ответ. Но я не совсем понимаю о «инициализированной» части. Означает ли это, что я должен очистить буфер структуры до того, как его повторно использовать? А что, если я использую malloc? – EricBkc
Рассмотрим 'int foo; printf ("% d", foo); '- какое значение будет напечатано? Доступ к значению 'foo' перед присвоением значения is считается« неопределенным поведением ». Доступ к нему может вернуть полузасушливое значение мусора (вероятно), это может привести к сбою программы или может форматировать ваш жесткий диск (крайне маловероятно, но это, по-видимому, канонический пример плохих вещей, которые могут произойти, когда вы идете в «неопределенные поведение"). Теперь рассмотрим 'int foo = 3; printf ("% d", foo); '- это всегда будет печатать '3', потому что foo теперь инициализируется (со значением 3). (cont) – keithmo
Теперь рассмотрим 'struct Pkt * pkt;' - 'pkt' - это указатель, но где он указывает? Пока значение не будет установлено, оно не определено. Вызов 'recv()' с неинициализированным указателем, поскольку буфер может привести к сбою приложения, повреждению критической памяти или форматированию жесткого диска (см. Выше). – keithmo