2012-04-13 223 views
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?

回答

0

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

绝对最简单的功能性溶液(无multithreadding)是设置插座无阻塞,并且在主线程轮询英寸这听起来像你想避免这样做,但。

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

另一个选项是设置套接字到非阻塞(下的Win32使用setsockopt的如此设置超时,下* nix中传递给它O_NONBLOCK标志)。这样,如果没有可读取的数据,它将返回控制权。但是这意味着您需要以合理的时间间隔轮询套接字(“合理”完全取决于您,以及您需要服务器如何快速处理新数据。)

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

有很多的方式进入异步程序的混乱,所以它可能是最好的保持它的简单,并得到它的工作,直到你满意的控制流。

+0

如果我每次发送内容时关闭连接,并在下次需要发送内容时打开一个新连接,这样我就可以避免阻塞。听上去怎么样? – 2012-04-13 15:04:49

+0

是的,你可以做到这一点(事实上,如果你只是推动状态更新,你可能也会如此)。问题在于服务器将在accept()上被阻塞,而不仅仅是在读取数据时。基本上你的服务器不能保证连接何时发生,因此需要不断的收听。你可以设置一个超时(两端),并依靠双方知道它们意图形成连接的时间,但这是一个容易出错的问题。编辑:但是,如果你的服务器需要做的唯一事情是进程状态更新,那么是的,这可以正常工作。 – Bhau 2012-04-13 15:22:54

+0

好吧,我不介意服务器是否在不停地收听。我最初的问题是我在不关闭连接的情况下调用send(),并且只发送第一个状态,并且我在类似案例中阅读了这里(http://stackoverflow.com/q/8347107/777510)我需要调用recv并发送一个循环来避免这种情况,我所要求的是如果我可以通过发送和关闭连接来避免该循环。所以我应该罚款吗? – 2012-04-13 15:42:46

相关问题