在WSADuplicateSocket上发送多个消息时会发生什么?

时间:2014-10-03 20:47:03

标签: c++ networking tcp

我正在寻找有关在同时发送的WSA套接字上同时发送时会发生什么的信息?这样安全吗?你能指点我任何特定的文档吗?

我是否需要在进程中传递某种消息来告诉哪个进程对于发送是活动的?我想我必须为收到这样做。

有人能举例说明这部分文件的含义吗?

  

共享套接字上的通知受WSAAsyncSelect和WSAEventSelect的通常限制。使用任何共享描述符发出这些调用中的任何一个都会取消套接字的任何先前事件注册,无论使用哪个描述符进行该注册。因此,共享套接字无法将FD_READ事件传递给进程A,将FD_WRITE事件传递给进程B.对于需要这种紧密协调的情况,建议开发人员使用线程而不是单独的进程。

2 个答案:

答案 0 :(得分:1)

正如documentation所述:

  

引用共享套接字的描述符可以独立用于I / O.但是, Windows套接字接口不实现任何类型的访问控制,因此需要在共享套接字上协调其操作所涉及的过程。共享套接字通常用于具有一个进程,即负责创建套接字并建立连接,以及负责信息交换的其他过程。

如果您有两个进程同时在共享套接字上发送,它们将相互重叠。就像单个进程中的两个线程同时发送到同一个套接字一样。因此,您需要协调发送以避免重叠。例如,您可以使用共享的命名互斥锁。

至于你提到的引用,如果你阅读相关文档,它应该是不言自明的:

WSAAsyncSelect() function

  

为套接字发出WSAAsyncSelect会取消同一套接字的任何先前WSAAsyncSelect或WSAEventSelect。例如,要接收读取和写入的通知,应用程序必须使用FD_READ和FD_WRITE调用WSAAsyncSelect,如下所示:

     

rc = WSAAsyncSelect(s,hWnd,wMsg,FD_READ | FD_WRITE);

     

无法为不同的事件指定不同的消息。以下代码不起作用;第二个调用将取消第一个调用的效果,只有FD_WRITE事件将报告消息wMsg2:

     

rc = WSAAsyncSelect(s,hWnd,wMsg1,FD_READ);
  rc = WSAAsyncSelect(s,hWnd,wMsg2,FD_WRITE);

WSAEventSelect() function

  

为套接字发出WSAEventSelect会取消同一套接字的任何先前WSAAsyncSelect或WSAEventSelect,并清除内部网络事件记录。例如,要将事件对象与读取和写入网络事件相关联,应用程序必须使用FD_READ和FD_WRITE调用WSAEventSelect,如下所示:

     

rc = WSAEventSelect(s,hEventObject,FD_READ | FD_WRITE);

     

无法为不同的网络事件指定不同的事件对象。以下代码不起作用;第二个调用将取消第一个的效果,只有FD_WRITE网络事件将与hEventObject2相关联:

     

rc = WSAEventSelect(s,hEventObject1,FD_READ);
  rc = WSAEventSelect(s,hEventObject2,FD_WRITE); //坏

因此,如果您有进程S与进程AB共享套接字,则无法A监听FD_READ个事件, B监听FD_WRITE个事件,反之亦然。这是一个全有或全无的交易。

答案 1 :(得分:0)

  1. 从两个线程写入同一个套接字是安全的。实际的send()函数是原子的:当你在其中时,没有其他人可以为同一个套接字输入它。因此,您无法获得数据交错,提供您正在使用单个send(),编写整个消息,您处于阻止模式:请参阅注释下方。

  2. 只有在您违反上述条件时才会这样做。

  3. 这意味着实际上只有一个进程可以同时在该套接字上使用select()。只要一个流程做到了这一点,另一个流程就会失去其兴趣'无论它选择什么,所以这些事件都不会发生。这通常正是您想要的,因为您不希望两个进程对同一个读取事件做出反应。但是,如果您还在选择写作,那么问题会更多。如果您根本没有选择,请不要担心这一点。

相关问题