2012-12-25 174 views
1

我是一個新手,C#,OOP,網絡和TCP/IP套接字...多個客戶端異步連接,同步發送/接收

我有一個關於異步TCP/IP套接字通信的使用的誤解。 我試圖創建一個服務器,等待幾個客戶端,並且每次客戶端連接它顯示像「用戶192.168.1.105:2421加入」

我認爲,當您使用BeginAccept()一個新的線程將被創建...每當有新用戶連接時,它都會處理與特定客戶端的通信。但是,以下代碼塊...並不會顯示第二個客戶端的消息。

我應該更改哪些內容,以便對於每個連接的客戶端,我都有一個單獨的線程負責執行?

class Server 
{ 
    Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
    //constructor 
    public Server() 
    { 
     listener.Bind(new IPEndPoint(IPAddress.Parse("192.168.1.100"), 9050)); 
     listener.Listen(10); 
     listener.BeginAccept(new AsyncCallback(OnConnectRequest), listener); 
     Console.Write("Server Running...\r\n"); 
    } 

    public void OnConnectRequest(IAsyncResult ar) 
    { 
     Socket listener = (Socket)ar.AsyncState; 
     NewConnection(listener.EndAccept(ar)); 
     listener.BeginAccept(new AsyncCallback(OnConnectRequest), listener); 
    } 

    //send a string message over a TCP socket 
    public void sendMSG(string msg,Socket socket) 
    { 
    //some code which sends data according to my protocol 
    } 

    public byte[] receiveMSG(ref Socket socket) 
    { 
    //some code which receives data according to my protocol 
    } 


    //function called whenever a NEW CLIENT is connected 
    public void NewConnection(Socket sockClient) 
    { 
     Console.WriteLine("user {0} has joined",sockClient.RemoteEndPoint); 
     byte[] msg = new byte[20]; 
     sockClient.Receive(msg); 
    } 

回答

2

BeginAccept()接受一個請求,所以你的異步回調只會被第一次請求調用一次。這是標準的C#異步模式。

如果您想接受多個請求,則在完成處理請求後,您需要再次撥打BeginAccept()。請參閱Asynchronous server socket multiple clients

編輯:

,如果你想允許的併發請求,你應該調用和NewConnection()BeginAccept()之間EndAccept()

public void OnConnectRequest(IAsyncResult ar) 
{ 
    Socket listener = (Socket)ar.AsyncState; 
    Socket accepted = listener.EndAccept(ar); 
    listener.BeginAccept(new AsyncCallback(OnConnectRequest), listener); 
    NewConnection(accepted); 
} 
+1

丹尼爾不'BeginAccept()'再打電話。但它永遠不會執行,因爲線程在它到達之前會被阻塞。 ('sockClient.Receive'上的'NewConnection()'塊)。但基本上你是對的:使用'BeginAccept()'的模式是不正確的。 – Codo

+0

非常感謝,我會試試看 – Daniel