我的socket服务器例程可以工作吗?

时间:2018-05-12 17:01:04

标签: c# sockets networking client-server

我正在尝试构建多个客户端 - 一个服务器结构。每个客户端连接到服务器和服务器维护这些连接。

客户端有两个线程(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()) ;
        }           
}

代码说明

  • Client_connect_socket_list:包含当前连接的客户端
  • client_connect_info_dict:为每个套接字映射的客户端连接信息字典作为密钥。
  • client_connect_info:包含(is_client_thread1_Handler_Active,is_client_thread2_Handler_Active)
  • 仅选择那些在Socket.Select
  • 之后可以读取的套接字
  • 为当前未创建处理程序的那些套接字运行处理程序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再次创建新的处理程序,并且出现问题。

我想知道这个方案是否存在严重问题,我不应该使用它。如果有,那么我想知道更好的方法来实现多个客户端 - 一个服务器有扩展空间。

0 个答案:

没有答案