gpt4 book ai didi

c - 套接字 sendto() 在上次成功调用后返回 EINVAL

转载 作者:行者123 更新时间:2023-11-30 18:11:18 24 4
gpt4 key购买 nike

我修改了this C数据报(UDP)套接字客户端示例:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <signal.h>

#define SERVERPORT "4950"

volatile sig_atomic_t is_shutdown = 0;

void handler_signal(int signal)
{
if (signal == SIGINT)
{
is_shutdown = 1;
}
}

int main(int argc, char *argv[])
{
int socket_fd;
struct addrinfo hints, *server_info, *temp;
int result;
int number_bytes;

if (argc != 2)
{
fprintf(stderr, "usage: executable [hostname]\n");
return 1;
}

memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;

result = getaddrinfo(argv[1], SERVERPORT, &hints, &server_info);

if (result != 0)
{
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(result));
return 1;
}

// loop through all the results and make a socket
for(temp = server_info; temp != NULL; temp = temp->ai_next)
{
socket_fd = socket(temp->ai_family, temp->ai_socktype, temp->ai_protocol);

if (socket_fd == -1)
{
fprintf(stderr, "socket error: %s\n", strerror(errno));
continue;
}

break;
}

freeaddrinfo(server_info);

if (temp == NULL)
{
fprintf(stderr, "failed to create socket\n");
return 2;
}

//int hostname_length = strlen(argv[2]);
unsigned long counter = 0;
const size_t buffer_length = 50;
char buffer[buffer_length];
memset(&buffer, 0, buffer_length);

while (!is_shutdown)
{
snprintf(buffer, buffer_length, "%lu", counter++);

number_bytes = sendto(socket_fd, buffer, buffer_length, 0, temp->ai_addr, temp->ai_addrlen);

if (number_bytes == -1)
{
fprintf(stderr, "sendto error: %s\n", strerror(errno));
break;
}

printf("sent %d bytes to %s.\n", number_bytes, argv[1]);
}

result = close(socket_fd);

if (result == -1)
{
fprintf(stderr, "close error: %s\n", strerror(errno));
}

printf("exiting application\n");

return 0;
}

在循环的第二次迭代中,sendto 函数失败,并出现无效参数 (errno 22)。它适用于第一个。

但是,如果我将其更改为以下内容,代码就可以工作(客户端不断以无限循环发送消息,服务器成功接收它们):

    //...

//create a copy to pass it later
socklen_t length = temp->ai_addrlen;
struct sockaddr *address = temp->ai_addr;

while (!is_shutdown)
{
snprintf(buffer, buffer_length, "%lu", counter++);

number_bytes = sendto(socket_fd, buffer, buffer_length, 0, address, length);

//...

我在这里做了什么?我缺少什么?我不确定这里发生了什么。

最佳答案

正如 Frankie_C 在他的[评论]中指出的那样:

temp 是指向 struct addrinfo 的指针,其值是从 server_info 分配的。但是当您freeaddrinfo(server_info)时,内存被释放,并且temp指向任何地方。它第一次起作用,因为还没有发生内存重用。但内存复用后就失效了。尝试先复制数据以释放结构。

关于c - 套接字 sendto() 在上次成功调用后返回 EINVAL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48735350/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com