我正在尝试构建多个客户端 - 一个服务器结构。每个客户端连接到服务器和服务器维护这些连接。
客户端有两个线程(thread1,thread2)异步运行并共享1个套接字来发送,接收。两个线程各包含多个发送,接收功能。对于服务器为每个客户端提供服务,它还必须创建两个共享1个套接字的客户端处理程序。
我希望我的服务器只有在他们的(每个客户端)套接字可以读取以节省资源时才创建客户端处理程序例程(异步任务)。我正在尝试使用'Socket.Select'方法实现此功能。
这是我假设使用接近c#的代码实现服务器端选择例程。
server.selectRoutine(){
while(!serverSocket.closed())
{
checkReadList client_connect_socket_list_copy=new ArrayList<Socket>(client_connect_socket_list) ;
Socket.Select(client_connect_socket_list_copy, null,null) ;
foreach(Socket s in client_connect_socket_list_copy)
{
client_connect_info info=client_connect_info_dict.Items[s] ;
if(!info.is_client_thread1_handler_active)
{
info.is_client_thread1_active=true ;
clServerEntranceHandler handler=new clServerEntranceHandler() ;
Task.Run(handler.run()) ;
}
if(!info.is_client_thread2_handler_active)
{
info.is_client_thread2_active=true ;
clServerExitHandler handler=new clServerExitHandler() ;
Task.Run(handler.run()) ;
}
}
代码说明
info.is_client_thread1_Handler_Active=false
。并设置info.is_client_thread1_Handler_Active=true
。这是因为在已经建立的处理程序中会有多个recv
函数,它们处于阻塞模式。因此,当客户端将消息发送到目标为recv
功能的服务器时,Socket.Select也会将此套接字视为准备读取,并最终创建新的处理程序。为避免这种情况,我需要检查处理程序是否处于活动状态。处理程序完成后,它会在里面设置info.is_client_thread1_Handler_Active= false
。对于client_thread2处理程序也是如此。我想我现在必须将此例程与已经创建的每个处理程序同步。例如,在Socket.Select看到消息队列中的消息A之后,避免处理程序P抢夺消息中的recv
函数的情况。处理程序P的套接字的消息队列内部。然后处理程序P将结束并设置info.is_Handler_Active=false
。然后selectRoutine
将为处理程序P已经读取的消息A再次创建新的处理程序,并且出现问题。
我想知道这个方案是否存在严重问题,我不应该使用它。如果有,那么我想知道更好的方法来实现多个客户端 - 一个服务器有扩展空间。