Jer*_*ter 1 c sockets udp network-programming recvfrom
所以,我在C中创建一个使用UDP的服务器,我想监听来自许多来源的传入数据包.因此,当我打电话时ssize_t recvfrom(int, void *, size_t, int, struct sockaddr * __restrict, socklen_t * __restrict),包含发件人信息的第五个参数可能会有所不同.
有没有办法在不知道每个客户的地址信息的情况下接收数据包?而且,这可能与C的库有关吗?
这是我的代码:
int file_descriptor;
char data[1024];
int bytes_recved;
sockaddr_in iDontKnow;
socklen_t addr_len = sizeof(iDontKnow);
if ((bytes_recved = recvfrom(file_descriptor, data, strlen(data), 0, (struct sockaddr*)&iDontKnow, &addr_len)) < 0) {
perror("Failed to receive data");
}
Run Code Online (Sandbox Code Playgroud)
我注意到,当使用Java的DatagramSocket和DatagramPacket类接收数据时,DatagramSocket的receive函数接受了DatagramPacket 类型的参数.但是,此DatagramPacket仅保存放置数据的对象.那么,为什么C的UDP接收实现要求您知道发送者的信息?
有没有办法在不知道每个客户的地址信息的情况下接收数据包?
好吧,无论如何,您无需事先知道发件人信息.收到数据包后,将存储发件人信息(如果有)address.
从手册页中,
Run Code Online (Sandbox Code Playgroud)ssize_t recvfrom(int socket, void *restrict buffer, size_t length, int flags, struct sockaddr *restrict address, socklen_t *restrict address_len);[...]如果address参数不是空指针且协议提供消息的源地址,则接收消息的源地址应存储在
sockaddraddress参数指向的结构中,并且该地址的长度应存储在address_len参数指向的对象中.
关于为什么部分,在无连接套接字的情况下,除非您知道通信中的数据包的发件人地址,否则您无法回复或回复发件人.因此,需要在无连接模式下专门知道发件人信息,并且随之而来的是recvfrom()与收到的数据一起向我们提供有关发件人的信息.
编辑:
在你的代码中
recvfrom(file_descriptor, data, strlen(data), 0, (struct sockaddr*)&iDontKnow, &addr_len)
Run Code Online (Sandbox Code Playgroud)
是错误的,就像strlen(data)UB一样,因为你试图计算未初始化的char数组的长度,该数组不符合字符串的条件.它调用未定义的行为.您可能想要使用sizeof(data),就像data数组一样.
如果您对发件人的信息不感兴趣,只需将a NULL作为相应的参数传递.
除此之外,对于无连接套接字(UDP),实际上需要获取发件人信息.对于面向连接的套接字,您有另一种精简替代方案,recv()它只负责接收和存储数据.