我正在尝试从UDP套接字读取数据,但在读取前255个字节后,read()
似乎丢弃套接字上的其余数据并阻塞,直到另一个数据克进入。< / p>
这是我正在使用的网络代码:
int sock;
struct sockaddr_in remote_addr, self_addr;
uint8_t network_init(uint16_t port)
{
memset((char *) &remote_addr, 0, sizeof(remote_addr));
remote_addr.sin_family = AF_INET;
remote_addr.sin_addr.s_addr = inet_addr("192.168.1.22");
remote_addr.sin_port = htons(3001);
memset((char *) &self_addr, 0, sizeof(self_addr));
self_addr.sin_family = AF_INET;
self_addr.sin_addr.s_addr = INADDR_ANY;
self_addr.sin_port = htons(3001);
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
fprintf(stderr, "Could not create socket.");
return 1;
}
else if (bind(sock, (struct sockaddr *) &self_addr, sizeof(self_addr)) != 0)
{
fprintf(stderr, "Could not bind to socket.");
return 1;
}
return 0;
}
void network_send(uint8_t *data, uint8_t len)
{
sendto(sock, data, len, 0, (struct sockaddr *) &remote_addr, sizeof(remote_addr));
}
void read_data()
{
int len = 0;
ioctl(sock, FIONREAD, &len);
// We have data
if (len > 0)
{
char *buffer = (char *) malloc(256);
uint8_t buflen;
printf("==== %d | Data:\n", len);
while (len > 0)
{
buflen = min(255, len);
len = len - buflen;
buffer[buflen] = '\0';
printf("len: %d, buflen: %d,\n",len, buflen);
read(sock, buffer, buflen);
printf("%s\n", buffer);
}
printf("\n");
}
}
这是我用来发送数据的命令:
echo -n '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567' | nc -u localhost 3001
这是输出:
==== 257 | Data:
len: 2, buflen: 255,
123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345
len: 0, buflen: 2,
^C
此外,执行此读取后,ioctl(sock, FIONREAD, &len);
生成0
的长度结果。我怀疑是由于某种原因,read()
在有机会被读取之前清除了其余的数据,但我似乎无法在任何文档中找到对此行为的任何引用。
我正在开发一台Ubuntu linux机器(x86_64
)。
答案 0 :(得分:2)
使用UDP套接字,每次调用read()
都会从内核中读取整个数据报。如果读缓冲区对于整个数据报不够大,则其余部分将被丢弃。它不像一个流套接字,你可以继续通电直到你得到所有东西。
由于FIONREAD
告诉您邮件中的字节数,因此您应将其用作malloc()
的大小,而不是256
:
if (len > 0) {
char *buffer = malloc(len);
...