read()/recv()函数是否会被卡住,即使我正在使用select()?

read()/recv()函数是否会被卡住,即使我正在使用select()?,c,sockets,select,C,Sockets,Select,我一直在学习套接字,我知道你可以通过线程或使用select()函数来处理客户机,对吗 据我所知,如果你打电话: select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); 该函数指示指定的文件描述符中的哪些已准备好读取、哪些已准备好写入或哪些具有挂起的错误条件,因此如果我随后调用: read(int fildes,void*buf,size\u t nbyte)

我一直在学习套接字,我知道你可以通过线程或使用select()函数来处理客户机,对吗

据我所知,如果你打电话:

select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
该函数指示指定的文件描述符中的哪些已准备好读取、哪些已准备好写入或哪些具有挂起的错误条件,因此如果我随后调用:

read(int fildes,void*buf,size\u t nbyte)
recv(int sockfd,void*buf,size\u t len,int标志)

函数将被卡住,直到至少在一个指定的文件描述符上找到要读取或接收的内容,或者直到需要传递的信号到达,并且该信号超时到达,对吗

那么,read()/recv()函数是否会无限期地被卡住,即使我使用select()和特定的超时

因为我正在尝试实现一个能够发送和接收消息和图像的客户端,它显然正确地发送了文件,但在收到图像后,程序会一直在read()中等待

这是一个函数,它负责在调用select()并确定将接收图像后接收图像

void receive_image(int sock, FILE *fp_write){
    char buffer[256];
    char byte;

    fp_write = fopen("archivoRecibido.bmp","wb");
    enviarConfirmacion(sock);
    enviarMD5SUM(sock);

    while(read(sock, &byte, sizeof(byte)) > 0){
        fwrite(&byte,sizeof(byte),1,fp_write);
    }
    fclose(fp_write);
    puts("***PERFECT***");
}

我怀疑我的知识是,理论上文件不应该关闭,也不应该接收图像,但事实并非如此,图像接收正确,发生的情况是,我无法返回主循环发送另一条消息,因为我认为它在读取时卡住了。

您正在循环中调用
read
select
只告诉你有东西要读,而不是要读多少。循环将消耗所有数据,然后阻塞
读取
。是否已将套接字设置为非阻塞?您将要查看。优秀的最新示例参考。如果套接字处于阻塞模式,并且您在循环中执行
send()
recv()
,或者以任何不受刚刚指示的
select()
指示的方式执行,则它们可以阻塞。具体来说,循环直到
recv()
返回零将阻塞,直到对等方关闭连接。通常将非阻塞模式与
select()
结合使用。如果套接字未处于非阻塞模式,则即使是通过轮询或选择返回为“ready for reading”(准备读取)的套接字上的第一次读取或recv也可能会阻塞,正如Linux select(2)手册页的bug部分中所述(但实际上这不是bug)。至于select()后面跟着一个读取循环直到eof,这个东西肯定起源于某个“教程”——我发现不太可能有那么多人不带着彼此进入那个洞;-)