请教一个Socket池的问题

StarsunYzL 2009-09-20 02:56:25
听说一些TCP服务端里有Socket池这样的设计,按照我的理解,池的概念就是预先创建好一定数量的资源,然后重复使用这些资源,当资源暂时不用时,就将资源标记为空闲,而不是销毁资源,这样就可以避免反复创建和销毁资源带来的开销。

把上面的概念套到Socket池上来,就是预先用socket/WSASocket创建好一定数量的SOCKET句柄,当有客户端连接时,从Socket池里取一个空闲的SOCKET句柄来分配给新连接的客户端,当客户端关闭时,就将对应SOCKET句柄标记为空闲,而不是用closesocket去关闭SOCKET句柄。

如果上面的Socket池理解正确,那我有两个问题不是很明白:
1、服务端接受连接时是不是只能用AcceptEx函数,因为只有AcceptEx才能自己指定接受连接的SOCKET句柄,而accept/WSAAccept则会自动创建一个新的SOCKET句柄,这样就没法用Socket池里已创建好的SOCKET句柄。

2、当客户端关闭时,服务端不能调用closesocket去关闭句柄。既然服务端不能调用closesocket,那服务端怎么主动去断开和客户端的连接,发消息给客户端吗?如果客户端也不closesocket呢,这个SOCKET句柄不就是关不了了吗?

如果上面的Socket池理解不正确,那正确的Socket池应该是怎样设计的呢?
...全文
140 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
fangle6688 2009-09-21
  • 打赏
  • 举报
回复
只有AcceptEx支持SOCKET池

对于DNS服务器、proxy服务器这样业务简单,瓶颈在于并发连接数的应用,应该考虑AcceptEx+SOCKET池

对于其他应用,通常瓶颈不在于并发连接数,而在于并发IO数,典型的如网络游戏、股票交易等,不应该考虑SOCKET池
StarsunYzL 2009-09-20
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 udknight 的回复:]
用上面的API就可以重用了。lz可以试试。
[/Quote]

OK,感谢帮助。我的疑惑基本上消除了,有了AcceptEx和DisconnectEx,大致知道怎么设计SOCKET池和SOCKET重用了。不过我还想听听其他人的意见,稍后结贴。
udknight 2009-09-20
  • 打赏
  • 举报
回复
用上面的API就可以重用了。lz可以试试。
StarsunYzL 2009-09-20
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 udknight 的回复:]
1 只能用AcceptEx
2 win2003下 DisconnectEx 
  winXP下TransmitFile
[/Quote]

查了下DisconnectEx和TransmitFile,确实可以只断开连接而不关闭SOCKET,以便AcceptEx重复使用原来的SOCKET来接受新连接,感谢!

这么说的话我理解的SOCKET池应该是正确的咯?
StarsunYzL 2009-09-20
  • 打赏
  • 举报
回复
还是不大明白,这样问吧,假如现在我用WSASocket创建了100个空闲的SOCKET,来组成一个SOCKET池,然后:

1、什么时候该从SOCKET池里取出空闲的SOCKET来使用?是当客户端连接上来的时候吗?

2、如果服务端主动断开就closesocket的话,那这个SOCKET不就是被销毁了吗?怎么还能继续保持下去以便下一次复用?这样的话下次还是得重新创建SOCKET吧。
udknight 2009-09-20
  • 打赏
  • 举报
回复
1 只能用AcceptEx
2 win2003下 DisconnectEx
winXP下TransmitFile
MoXiaoRab 2009-09-20
  • 打赏
  • 举报
回复
主动断开,那就Close咯

第一次创建过,以后就用这个。池中的Socket对象不变,变的是连接对象

池的优点在于不要再创建Socket,但不是不创建Connect
StarsunYzL 2009-09-20
  • 打赏
  • 举报
回复
先谢谢回答。

1、每次成功调用WSAAccept都会返回一个SOCKET,以后和客户端的收发数据都通过这个SOCKET。问题是这个SOCKET是由WSAAccept返回的,而不是从已创建好的SOCKET池里取的,这样的话那SOCKET池的作用在哪呢?

2、我的意思是当连接还在的时候,服务端怎么去主动断开这个连接。比如有一个已经连接好的正常客户端,服务端想主动把这个客户端断开,该怎么做?

可能我对SOCKET池的理解有问题,那SOCKET池的正确工作原理是怎么样的呢?



MoXiaoRab 2009-09-20
  • 打赏
  • 举报
回复
1、服务端接受连接时是不是只能用AcceptEx函数,因为只有AcceptEx才能自己指定接受连接的SOCKET句柄,而accept/WSAAccept则会自动创建一个新的SOCKET句柄,这样就没法用Socket池里已创建好的SOCKET句柄。
=======================
若无错误发生,WSAAccept()函数返回所接受套接口的描述字,又不是非要创造一个新的不可。真搞不懂你了。服务端怎么接受都是没关系的,只要保持住一开始的那个套接字就行了

如果真的新建了,那就重新连接么。又没关系的。

2、当客户端关闭时,服务端不能调用closesocket去关闭句柄。既然服务端不能调用closesocket,那服务端怎么主动去断开和客户端的连接,发消息给客户端吗?如果客户端也不closesocket呢,这个SOCKET句柄不就是关不了了吗?
========================
连接都不在了,难道Socket就这么永远存在下去?要是大家都开着浏览器不关,然后直接断网,服务器岂不是就得崩溃?大量的垃圾Socket存在?

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧