0

这是我的情况,我有一个服务器正在监听连接,还有一个我现在正在编程的客户端。客户端没有从服务器接收任何内容,但它必须每 3 分钟发送一次状态更新。

我目前有以下内容:

    WSAStartup(0x101,&ws);
    sock = socket(AF_INET,SOCK_STREAM,0);
    sa.sin_family = AF_INET;
    sa.sin_port = htons(PORT_NET);
    sa.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    connect(sock,(SOCKADDR*)&sa,sizeof(sa));
    send(sock,(const char*)buffer,128,NULL);

我的方法应该如何?我可以避免循环recv吗?

4

1 回答 1

0

这取决于您想要的行为和程序结构。默认情况下,套接字将阻止任何读取或写入操作,这意味着如果您尝试让服务器的主线程轮询连接,您最终将“冻结”3分钟或直到客户端关闭联系。

最简单的功能解决方案(无多线程)是将套接字设置为非阻塞,并在主线程中轮询。听起来你想避免这样做。

最明显的解决方法是为每个连接创建一个专用线程,以及主侦听器套接字。您的服务器侦听传入连接并为它创建的每个流套接字生成一个线程。然后每个连接线程在它的套接字上阻塞,直到它接收到数据,然后自己处理它或者将它分流到一个共享队列中。这是一个庞大而复杂的解决方案——需要打开和关闭的多个线程,需要保护的共享资源。

另一种选择是将套接字设置为非阻塞(在 win32 下使用 setsockopt 设置超时,在 *nix 下将 O_NONBLOCK 标志传递给它)。这样,如果没有可读取的数据,它将返回控制权。然而,这意味着您需要以合理的时间间隔轮询套接字(“合理”完全取决于您,以及您需要服务器多快对新数据采取行动。)

就个人而言,对于您所描述的轻量级用途,我将使用上述组合:一个单独的专用线程,每隔几秒轮询一个套接字(或一组非阻塞套接字),在两者之间休眠,然后简单地将数据推送到主线程在其主循环期间执行的队列。

有很多方法可以使异步程序陷入混乱,因此最好保持简单并使其正常工作,直到您对控制流感到满意为止。

于 2012-04-13T14:46:49.670 回答