WSA发送到多线程iocp服务器中的所有已连接套接字 [英] WSAsend to all connected socket in multithreaded iocp server

查看:91
本文介绍了WSA发送到多线程iocp服务器中的所有已连接套接字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在IOCP Server上工作(I/O重叠,4个线程,CreateIoCompletionPortGetQueuedCompletionStatusWSASend等).我还创建了一个自动重置事件,并将每个异步I/O操作的句柄置于OVERLAPPED结构中.

I work on IOCP Server (Overlapped I/O , 4 threads, CreateIoCompletionPort, GetQueuedCompletionStatus, WSASend etc). I also created an auto-reset event and put the handle in the OVERLAPPED structure for each asynchronous I/O operations.

问题是:如何正确发送缓冲区给所有连接的套接字呢?每个套接字都存储在上下文信息结构的链接列表中.

And the question is: How to send buffer too all connected sockets properly? Each socket is stored in linked list of context info structures.

我不确定下面的方法还可以吗?

I'm not sure is that approach below is ok?

...
DWORD WINAPI WorkerThread() { // 1 of 4 workthread
...
GetQueuedCompletionStatus(...);
...
PPER_SOCKET_CONTEXT  pTmp1, pTmp2;
pTmp1 = g_pCtxtList; // start of linked list with sockets
EnterCriticalSection(&g_CriticalSection);
while( pTmp1 ) 
{  
pTmp2 = pTmp1->pCtxtBack;
         WaitForSingleObject(pTmp1->pIOContext->Overlapped.hEvent,infinite);                
          // if there is any pending wsasend on this socket,wait to completed, so
          // we can post another wsasend using the same overlapped structure
          // and buffer
           WSASend(pTmp1->Socket,...,&(pTmp1->pIOContext->Overlapped), NULL);
       pTmp1 = pTmp2;
 }
LeaveCriticalSection(&g_CriticalSection);
...
}

如果另一个线程也尝试同时执行相同的工作会发生什么?
在所有线程中使用GQCS并等待功能是一个好主意吗?
有关在多线程iocp服务器中的所有客户端wsasends的任何线索,将不胜感激.

And what happens if another thread also tries to do the same work at same time?
Is that good idea to use GQCS and waits function in all threads?
Any clue about wsasends to all clients in multithreaded iocp server will be appreciated.
thx

推荐答案

正如Martin所说,这将非常糟糕,并且可能会破坏在发送给所有人的整个过程中使用您锁定的套接字列表的所有内容的性能.连接.您没有说这是UDP还是TCP,但是如果是TCP,请注意,您现在正在将对服务器性能的控制移交给客户端,因为在慢速客户端连接上的TCP流控制可能会导致写入完成延迟(请参见此处)-和我假设您正在使用写入完成功能来触发事件?

As Martin says, this will perform terribly and likely kill the performance of anything that uses the list of sockets that you lock for the entire duration of your send to all connections. You don't say if this is UDP or TCP but if it's TCP be aware that you are now handing control of your server's performance over to the clients as TCP flow control on a slow client connection may cause the write completion to be delayed (see here)- and I assume you're using the write completion to trigger the event?

我假设您的实际要求是要避免在服务器上复制数据并分配多个缓冲区,由于内存限制或因为您已对内存副本进行了概要分析并发现其昂贵,因此每个连接一个缓冲区.

I assume that your actual requirement is that you want to avoid copying the data on the server and allocating multiple buffers, one for each connection either due to memory constraints or because you've profiled the memory copy and found that it's expensive.

我处理此问题的方法是让单个引用计数的缓冲区和一个缓冲区句柄",这只是一个稍微扩展的重叠结构,它引用了单个数据缓冲区并提供了所需的WSABUF.然后,您可以使用唯一的缓冲区句柄"向每个连接发出即发即弃"写入操作,所有这些都指向单个基础缓冲区.一旦所有写操作完成,缓冲区上的ref计数将减少为零并进行清理-正如Martin所说,最好通过将缓冲区放入池中供以后重用来实现清理.

The way I deal with this is to have a single reference counted buffer and a 'buffer handle' which is just a slightly extended overlapped structure which references your single data buffer and provides the WSABUF that you need. You can then issue a 'fire and forget' write to each connection using a unique 'buffer handle' all of which refer to the single underlying buffer. Once all writes complete the ref count on the buffer is reduced to zero and it cleans up - and as Martin says, that clean up is best achieved by putting the buffer into a pool for later reuse.

注意::我不确定我是否真正了解您的意图(因此我原本删除了我的答案),如果我没有关注,请告诉我,我会进行调整...

Note: I'm not sure that I actually understand what you are trying to do (so I orginally deleted my answer), let me know if I'm not following and I'll adjust...

这篇关于WSA发送到多线程iocp服务器中的所有已连接套接字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆