select()和具有C上动态缓冲区的非阻塞recv

皮特·达罗(Pete Darrow)

我试图弄清楚为什么recv在下面的代码中被阻止,如果我通过telnet并发送“ GET / HTTP / 1.1”,则recv会一直在等待数据并阻止另一个telnet连接。但是,如果我只是使用固定的缓冲区而不是,它就可以正常工作并且不会阻塞do{} while,即,

char buffer[1024];
nbytes = recv(i, buffer, sizeof buffer, 0);

到目前为止,我所了解的select()处于准备就绪的状态。我需要设置recvO_NONBLOCK吗?

char *buffer = NULL;
unsigned long LEN = 200;
unsigned long bytes_received = 0;
unsigned long cur_size = 0;
int status = 0;

FD_SET(listener, &master);
fdmax = listener;

for(;;){
    read_fds = master; // copy it
    if(select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1){
        exit(4);
    }   

    for(i = 0; i <= fdmax; i++){
        if(FD_ISSET(i, &read_fds)){
            if(i == listener){
                // handle new connections
                addrlen = sizeof remoteaddr;
                newfd = accept(listener, (struct sockaddr *)&remoteaddr, &addrlen);

                if(newfd == -1){
                    perror("accept");
                }else{
                    FD_SET(newfd, &master);
                    if(newfd > fdmax) { 
                        fdmax = newfd;
                    }
                }
            }else{
                do{
                    if(bytes_received >= cur_size){
                        char * tmp;
                        cur_size += LEN;
                        tmp = realloc(buffer, cur_size);
                        buffer = tmp;
                    }
                    status = recv(i, buffer + bytes_received, LEN, 0); 
                    if(status == 0){ 
                        printf("Done\n");
                    }
                    else if(status > 0){ 
                        bytes_received += status;
                    }
                    else{
                        fprintf(stderr, "socket error\n");
                    }
                } while (status > 0); 
                if(send(i, buffer, strlen(buffer), 0) == -1){
                    perror("send");
                }   
            }   
        }   
    }
}
大卫·施瓦兹(David Schwartz)

首先,如果您不想阻塞,则必须将套接字设置为非阻塞。无论您做什么,都无法确保如果套接字操作正在阻塞,则永远不会阻塞。这是一个常见的错误,已导致严重的错误,并带有重大的安全隐患。如果必须阻止,则必须将套接字设置为非阻止。

到目前为止,我了解到的是select()处于就绪状态。

您的意思处于随时可以阅读的状态。select函数是一个状态报告功能,与其他状态报告功能一样,它会在调用它和返回它之间的某个时间点报告状态。无法保证在以后的某个时刻仍保持该状态。

永远不要认为您可以排除状态可能改变的所有其他可能方式。历史充满了那些认为并被焚毁的人。

但是阻塞的特定原因是您在recv没有先调用的情况下进行调用select(因为您有一个再次do调用循环recv)。

无论如何,您都必须正确处理WOULDBLOCK来自指示recv那是必不可少的。

此外,您可能希望recv每个select匹配一次电话如果您解决了其他问题,那就没关系了。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

非阻塞或阻塞分配的缓冲区?

来自分类Dev

Java中的非阻塞缓冲区

来自分类Dev

具有Qt的C ++缓冲区

来自分类Dev

c + +和DX11中的动态常量缓冲区或动态顶点缓冲区

来自分类Dev

具有动态缓冲区的Windows读取文件

来自分类Dev

具有X文件的非相干顶点缓冲区

来自分类Dev

具有X文件的非相干Vertex缓冲区

来自分类Dev

C ++:具有缓冲区和指针循环的功能-是否有可能进行优化?

来自分类Dev

PHP:是否可以获取非阻塞输出缓冲区?

来自分类Dev

C ++ TCP Recv未知缓冲区大小

来自分类Dev

使用从recv()tcpServer c获取的缓冲区的分段错误

来自分类Dev

C recv()未在缓冲区中读取

来自分类Dev

C-当stdin的缓冲区中已经有数据时,在stdin上执行select()

来自分类Dev

当缓冲区太大时fgets()阻塞

来自分类Dev

返回从缓冲区和函数读取的字符串而没有动态分配?

来自分类Dev

Boost.Asio-具有自定义缓冲区的多个缓冲区

来自分类Dev

具有多个绘制缓冲区的帧缓冲区

来自分类Dev

具有smart_ptr和weak_ptr的循环缓冲区?

来自分类Dev

perl gunzip的缓冲区和gunzip的文件具有不同的字节顺序

来自分类Dev

将带有动态字符串的结构复制到缓冲区c

来自分类Dev

如何避免异步非阻塞WSASend调用上的缓冲区溢出

来自分类Dev

解码图片缓冲区和编码图片缓冲区之间有区别吗?

来自分类Dev

修改具有缓冲区溢出漏洞的C函数的返回地址

来自分类Dev

C ++-从具有相同功能的文件或内存缓冲区中读取

来自分类Dev

具有固定大小缓冲区的C中的read()函数无法返回预期结果

来自分类Dev

C中的缓冲区溢出,具有分配双精度数组的功能

来自分类Dev

目标C中的动态缓冲区(使用ARC)

来自分类Dev

具有神秘缓冲区的套接字

来自分类Dev

XGetImage具有预先分配的内存缓冲区

Related 相关文章

  1. 1

    非阻塞或阻塞分配的缓冲区?

  2. 2

    Java中的非阻塞缓冲区

  3. 3

    具有Qt的C ++缓冲区

  4. 4

    c + +和DX11中的动态常量缓冲区或动态顶点缓冲区

  5. 5

    具有动态缓冲区的Windows读取文件

  6. 6

    具有X文件的非相干顶点缓冲区

  7. 7

    具有X文件的非相干Vertex缓冲区

  8. 8

    C ++:具有缓冲区和指针循环的功能-是否有可能进行优化?

  9. 9

    PHP:是否可以获取非阻塞输出缓冲区?

  10. 10

    C ++ TCP Recv未知缓冲区大小

  11. 11

    使用从recv()tcpServer c获取的缓冲区的分段错误

  12. 12

    C recv()未在缓冲区中读取

  13. 13

    C-当stdin的缓冲区中已经有数据时,在stdin上执行select()

  14. 14

    当缓冲区太大时fgets()阻塞

  15. 15

    返回从缓冲区和函数读取的字符串而没有动态分配?

  16. 16

    Boost.Asio-具有自定义缓冲区的多个缓冲区

  17. 17

    具有多个绘制缓冲区的帧缓冲区

  18. 18

    具有smart_ptr和weak_ptr的循环缓冲区?

  19. 19

    perl gunzip的缓冲区和gunzip的文件具有不同的字节顺序

  20. 20

    将带有动态字符串的结构复制到缓冲区c

  21. 21

    如何避免异步非阻塞WSASend调用上的缓冲区溢出

  22. 22

    解码图片缓冲区和编码图片缓冲区之间有区别吗?

  23. 23

    修改具有缓冲区溢出漏洞的C函数的返回地址

  24. 24

    C ++-从具有相同功能的文件或内存缓冲区中读取

  25. 25

    具有固定大小缓冲区的C中的read()函数无法返回预期结果

  26. 26

    C中的缓冲区溢出,具有分配双精度数组的功能

  27. 27

    目标C中的动态缓冲区(使用ARC)

  28. 28

    具有神秘缓冲区的套接字

  29. 29

    XGetImage具有预先分配的内存缓冲区

热门标签

归档