TServerSocket最多同时支持多少个连接?

hughjane 2005-09-08 05:35:03
TServerSocket最多同时支持多少个连接?
服务器:TServerSocket
客户端:TClientSocket 100个左右同时连接
非阻塞方式通信,请有经验的高手看看服务器能否应付过来?应该注意什么?
...全文
1337 22 打赏 收藏 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
Friecin 2006-05-31
  • 打赏
  • 举报
回复
这里好热闹~ 路过.....

pp616 2006-05-21
  • 打赏
  • 举报
回复
《windows网络编程》这本书挺好的。建议楼主读读。
jsfserver 2006-05-20
  • 打赏
  • 举报
回复
抽象出一个完成端口大概的处理流程:
1:创建一个完成端口。
2:创建一个线程A。
3:A线程循环调用GetQueuedCompletionStatus()函数来得到IO操作结果,这个函数是个阻塞函数。
4:主线程循环里调用accept等待客户端连接上来。
5:主线程里accept返回新连接建立以后,把这个新的套接字句柄用CreateIoCompletionPort关联到完成端口,然后发出一个异步的WSASend或者WSARecv调用,因为是异步函数,WSASend/WSARecv会马上返回,实际的发送或者接收数据的操作由WINDOWS系统去做。
6:主线程继续下一次循环,阻塞在accept这里等待客户端连接。
7:WINDOWS系统完成WSASend或者WSArecv的操作,把结果发到完成端口。
8:A线程里的GetQueuedCompletionStatus()马上返回,并从完成端口取得刚完成的WSASend/WSARecv的结果。
9:在A线程里对这些数据进行处理(如果处理过程很耗时,需要新开线程处理),然后接着发出WSASend/WSARecv,并继续下一次循环阻塞在GetQueuedCompletionStatus()这里。


归根到底概括完成端口模型一句话:
我们不停地发出异步的WSASend/WSARecv IO操作,具体的IO处理过程由WINDOWS系统完成,WINDOWS系统完成实际的IO处理后,把结果送到完成端口上(如果有多个IO都完成了,那么就在完成端口那里排成一个队列)。我们在另外一个线程里从完成端口不断地取出IO操作结果,然后根据需要再发出WSASend/WSARecv IO操作。
jsfserver 2006-05-20
  • 打赏
  • 举报
回复
有,不过我不写注释的,你自己去看,看不明白我也没办法
完成端口的基本思路也是"阻塞+ 多线程",只不过一个是你自己控制阻塞和管理并调用线程,而完成端口全是由系统来帮你阻塞和管理并调用线程,虽然我不能说你们的做的不够好,但我想写windows的人更能了解自己的东西,他做出来的完成端口肯定有着他的优势.
mdf2008 2005-12-11
  • 打赏
  • 举报
回复
我也喜欢"阻塞+ 多线程",以这种方式写c/s之间的交互,觉得比较理想化.

rudolf_he 2005-12-02
  • 打赏
  • 举报
回复
jsfserver

能否提供更详细的 “完成端口模式下的高性能网络服务器” 的资料?

谢谢!!
tsk 2005-12-02
  • 打赏
  • 举报
回复
早听说用完成端口模式,只是不会用....
GaoLun 2005-12-02
  • 打赏
  • 举报
回复
我和 binbin(破坏分子) ( ) 一样,
习惯阻塞+ 多线程
jsfserver 2005-11-29
  • 打赏
  • 举报
回复
完成端口模式下的高性能网络服务器
完成端口听起来好像很神秘和复杂,其实并没有想象的那么难。这方面的文章在论坛上能找到的我差不多都看过,写得好点的就是CSDN.NET上看到的一组系列文章,不过我认为它只是简单的翻译了一下Network Programming for Microsoft Windows 2nd 中的相关内容,附上的代码好像不是原书中的,可能是另一本外文书里的。我看了以后,觉得还不如看原版的更容易理解。所以在我的开始部分,我主要带领初学者理解一下完成端口的有关内容,是我开发的经验,其他的请参考原书的相关内容。
采用完成端口的好处是,操作系统的内部重叠机制可以保证大量的网络请求都被服务器处理,而不是像WSAAsyncSelect 和WSAEventSelect的那样对并发的网络请求有限制,这一点从上一章的测试表格中可以清楚的看出。
完成端口就像一种消息通知的机制,我们创建一个线程来不断读取完成端口状态,接收到相应的完成通知后,就进行相应的处理。其实感觉就像WSAAsyncSelect一样,不过还是有一些的不同。比如我们想接收消息,WSAAsyncSelect会在消息到来的时候直接通知Windows消息循环,然后就可以调用WSARecv来接收消息了;而完成端口则首先调用一个WSARecv表示程序需要接收消息(这时可能还没有任何消息到来),但是只有当消息来的时候WSARecv才算完成,用户就可以处理消息了,然后再调用一个WSARecv表示等待下一个消息,如此不停循环,我想这就是完成端口的最大特点吧。
Per-handle Data 和 Per-I/O Operation Data 是两个比较重要的概念,Per-handle Data用来把客户端数据和对应的完成通知关联起来,这样每次我们处理完成通知的时候,就能知道它是哪个客户端的消息,并且可以根据客户端的信息作出相应的反应,我想也可以理解为Per-Client handle Data吧。Per-I/O Operation Data则不同,它记录了每次I/O通知的信息,比如接收消息时我们就可以从中读出消息的内容,也就是和I/O操作有关的信息都记录在里面了。当你亲手实现完成端口的时候就可以理解他们的不同和用途了。
CreateIoCompletionPort函数中有个参数NumberOfConcurrentThreads,完成端口编程里有个概念Worker Threads。这里比较容易引起混乱,NumberOfConcurrentThreads需要设置多少,又需要创建多少个Worker Threads才算合适?NumberOfConcurrentThreads的数目和CPU数量一样最好,因为少了就没法利用多CPU的优势,而多了则会因为线程切换造成性能下降。Worker Threads的数量是不是也要一样多呢,当然不是,它的数量取决于应用程序的需要。举例来说,我们在Worker Threads里进行消息处理,如果这个过程中有可能会造成线程阻塞,那如果我们只有一个Worker Thread,我们就不能很快响应其他客户端的请求了,而只有当这个阻塞操作完成了后才能继续处理下一个完成消息。但是如果我们还有其他的Worker Thread,我们就能继续处理其他客户端的请求,所以到底需要多少的Worker Thread,需要根据应用程序来定,而不是可以事先估算出来的。如果工作者线程里没有阻塞操作,对于某些情况来说,一个工作者线程就可以满足需要了。

loakia 2005-11-19
  • 打赏
  • 举报
回复
路过,学习一下

kinglh 2005-09-21
  • 打赏
  • 举报
回复
走过,,
lander9999 2005-09-20
  • 打赏
  • 举报
回复
学习
binbin 2005-09-17
  • 打赏
  • 举报
回复
偶只会用线程+阻塞方式,也许是思维方式的问题:-(
nike_ljq 2005-09-13
  • 打赏
  • 举报
回复
mark
jishiping 2005-09-13
  • 打赏
  • 举报
回复
服務器端采用非阻塞型时,如果Server与一个Client处理的时间需要1秒,那么在这1秒内,别的Client就无法链接进来。但是采用阻塞型时,由于是多线程,所以可以同时接收其它Client的连接。

256內存﹐P4 2.0G的PC,不能算是普通PC了吧。我3年前的电脑,用的都是P4 1.8的CPU和512MB的内存。现在的普通PC,至少应该是P4 2.8G以及512MB内存吧。
FengSC 2005-09-13
  • 打赏
  • 举报
回复
我觉得你对于100个左右的同时连接使用“线程阻塞”方式已经不是很好了,如果你需要高性能的服务器你必须使用其他方法解决,可以考虑使用select或直接使用IOCP方式。
storm999 2005-09-13
  • 打赏
  • 举报
回复
借貴貼問一下
季老大﹐服務器端采用阻塞式為什么會比非阻塞好?一台普通PC(256內存﹐P4 2.0G)大概能同時連多少個客戶端?
hughjane 2005-09-09
  • 打赏
  • 举报
回复
多谢!哪里有阻塞式通信的例子啊?据说阻塞式通信效率比较低,应该怎么去维护每个连接呢?
jishiping 2005-09-09
  • 打赏
  • 举报
回复
TServerSocket采用阻塞模式时,每个连接就是一个线程,线程对象中包含Socket对象,所以管理连接比采用非阻塞型的还要方便。自己写一个线程(由class TServerClientThread派生),同时重载它的虚拟函数ClientExecute(),在ClientExecute()中写代码。

class TSrvThread : public TServerClientThread
{
public:
__fastcall TSrvThread(TServerClientWinSocket*);
protected:
void __fastcall ClientExecute();
};

__fastcall TSrvThread::TSrvThread(TServerClientWinSocket* socket)
: TServerClientThread(true,socket)
{
//可以添加你的其它代码
}

void __fastcall TSrvThread::ClientExecute()
{
// ClientSocket 就是和客户端连接的socket
try {
//你的代码
}
catch(Exception& e) {
}
}

在 TServerSocket 的事件 OnGetThread 中写代码:
void __fastcall TModule1::ServerSocketGetThread(TObject *Sender,
TServerClientWinSocket *ClientSocket, TServerClientThread *&SocketThread)
{
SocketThread = new TSrvThread(ClientSocket);
if (SocketThread!=0) SocketThread->Resume();
}
我不懂电脑 2005-09-08
  • 打赏
  • 举报
回复
一两百个没问题。
加载更多回复(1)

1,317

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 网络及通讯开发
社区管理员
  • 网络及通讯开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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