我很困惑:是否有可能/建议在fd上组合线程并选择? 例如:我想创建一个线程tcp客户端 - 服务器程序,客户端可以向服务器发送消息,服务器将其传播到所有连接的客户端(客户端可以继续通信)。
我制作了一个服务器客户端程序,其中所有客户端在连接时都获得了一个单独的线程;但我在beej指南中读到“如果你在accept()调用时阻塞怎么办?你怎么同时收到recv()数据?”使用非阻塞套接字!“没办法!你不想要什么,然后呢?“
在这种情况下,我看不出阻塞意味着什么;因为在我的程序中,当我输入文本并按下输入时,文本被发送到服务器,但为什么他的意思是同时接收数据?我在输入文字的时候?怎么可能?我想我很困惑:p 我认为这些是解决方案的完全不同的方式,但我再也看不到选择提供的优势? THX
答案 0 :(得分:1)
当然可以使用多个调用select
的线程,但不是必需的。服务器只需一个线程即可为所有客户端提供服务。怎么样?一次一个。 select
函数(及其替换项,例如poll
,epoll
等)可以在您提供的集合中的某个套接字上发生事件时通知您。当select
套接字listen
时,accept
也会通知您。因此,服务器只能有一个事件循环处理侦听和连接套接字。
至于优点和缺点,我只会给你一个The C10K problem文章的链接。这是一场相当古老的辩论。
答案 1 :(得分:0)
在这种情况下,我看不出阻塞意味着什么;因为在我的程序中,当我输入文本并按下输入时,文本被发送到服务器,但为什么他的意思是同时接收数据?
当然可以。对于例如您可以select()
选择fd并在其他线程中处理它们(因此持续时间不会阻止select()
上可能发生的其他事件。)
在这种情况下,我看不出阻塞意味着什么;因为在我的程序中,当我输入文本并按下输入时,文本被发送到服务器,但为什么他的意思是同时接收数据?
他可能意味着当你有一个用于接受和接收数据的线程时,你可以阻止(等待)接受或接收。阻止意味着您正在等待传入连接(接受)或传入的已发送数据(接收)。如果您使用非阻塞套接字,如果没有事件发生,它将返回-1 EWOULDBLOCK
或EAGAIN errno
。
您可以在select()
上等待,同时使用您的listen fd和已连接的客户端fd。然后你可以同时等待fd上你想要的任何事件(新连接,接收数据等)