gpt4 book ai didi

c - Linux,C,epoll()读取: server did not get notified for the rest bytes

转载 作者:行者123 更新时间:2023-11-30 17:10:49 27 4
gpt4 key购买 nike

这是讨论此主题的新线程:Linux, C, epoll(), read() data incompleted?

我的 epoll() 服务器套接字使用 Level-Trigger 模式。

客户端发送10*128K数据;

服务器端,我使用了64K的缓冲区来接收,所以我应该至少被通知20次来接收来自客户端的所有字节。

但是我的调试显示我只收到了 19 次通知,并且缺少一些字节!为什么我没有收到剩余字节的通知?

========编辑1=======

基本上,客户端确实发送了这些字节,并且这些字节应该到达服务器端。 (因为我可以通过另一个函数来接收它们,即尽力读取所有字节并返回,直到没有更多字节可供读取 - 但这会导致接收性能低下)。

但是到了这个Nread(),我应该被通知并且Nread应该被调用20次以上,但现在它只被调用了19次。

查看代码:

efd = epoll_create1 (0);
event.data.fd = listener_fd;
event.events = EPOLLIN | EPOLLET;
epoll_ctl(efd, EPOLL_CTL_ADD, listener_fd, &event);

while (1){
n_fds = epoll_wait (efd, events, MAX_EPOLL_EVENTS, -1);
for (i = 0; i < n_fds; i++){
...........
if (islistener) {
.....
//handle new connections
}
else{
bzero(buffer, recv_buf_size);
if ((n= Nread(fd, buffer, recv_buf_size)) <= 0) {
//error
}
else
{
//add bytes to total:
__sync_fetch_and_add(&(mythreads->total_bytes_transferred), n) ;
}

}

int Nread(int fd, char *buffer, size_t count)
{
ssize_t r;
size_t left = count;
printf("===>\n");
while (left > 0){
r = read(fd, buffer, left);
printf("data: %ld\n", r);
if (r < 0) {
if (errno == EINTR || errno == EAGAIN)
break;
else
return -100; //error
else if (r == 0)
break;
}
left -= r;
buffer += r;
}
printf("=> done, %ld\n", count - left);
return count - left;
}

输出:

1===>
data: 65536
=> done, 65536
2===>
data: 65536
=> done, 65536
3===>
data: 60734
data: 4802
=> done, 65536
4===>
data: 55934
data: -1
errno: 11
=> done, 55934 //data is not enough. the missing part should come soon. but why I am not notified?
5===>
data: 60736
data: 4800
=> done, 65536
6===>
data: 65536
=> done, 65536
7===>
data: 65536
=> done, 65536
8===>
data: 65536
=> done, 65536
9===>
data: 65536
=> done, 65536
10===>
data: 65536
=> done, 65536
11===>
data: 65536
=> done, 65536
12===>
data: 65536
=> done, 65536
13===>
data: 65536
=> done, 65536
14===>
data: 65536
=> done, 65536
15===>
data: 65536
=> done, 65536
16===>
data: 65536
=> done, 65536
17===>
data: 65536
=> done, 65536
18===>
data: 65536
=> done, 65536
19===>
data: 65536
=> done, 65536

最佳答案

if ((n= Nread(fd, buffer, recv_buf_size)) <= 0) {
//error

流结束不是错误。见下文。

//data is not enough. the missing part should come soon. but why I am not notified?

已收到通知。这就是您阅读下一篇文章的原因。但您不仅获得了剩余的 65536-55934 字节,下次您还获得了整个缓冲区。

您没有任何理由期望每次发出读取时都有 65536 字节。如果愿意的话,TCP 可以一次传送一个字节。唯一相关的问题是您是否获得了预期的所有字节,并且您不会说您没有。

其他说明:

  • 如果r == 0则打印errno无效。您没有区分错误和流结束这两种情况。

  • 您也没有区分任何错误情况。仅当 errno == EAGAIN 时重新读取才有效。

  • 我根本不明白 Nread() 方法的意义。只是需要破解更多代码。只需从 epoll() 循环内部调用 read()recv() 即可。

关于c - Linux,C,epoll()读取: server did not get notified for the rest bytes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32705787/

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