2011-08-29 140 views
0

我有一個服務器應用程序和客戶端應用程序的功能已經工作。讓我告訴你,我怎麼我的客戶端應用程序連接到我的服務器應用程序:管理多個/多個TCP連接

現在
       //SERVER 
      // instantiate variables such as tempIp, port etc... 
      // ... 
      // ...  

      server = new TcpListener(tempIp, port); //tempIp is the ip address of the server. 

      // Start listening for client requests. 
      server.Start(); 

      // Buffer for reading data 
      Byte[] bytes = new Byte[MaxChunkSize]; 
      String data = null; 


      // Enter the listening loop. 
      while (disconect == false) 
      { 
       Console.Write("Waiting for a connection... "); 

       // Perform a blocking call to accept requests. 
       // You could also user server.AcceptSocket() here. 
       client = server.AcceptTcpClient(); // wait until a client get's connected... 
       Console.WriteLine("Connected!"); 

       // Get a stream object for reading and writing 
       stream = client.GetStream(); 

       // now that the connection is established start listening though data 
       // sent through the stream.. 
       int i; 
       try 
       { 
        // Loop to receive all the data sent by the client. 
        while ((i = stream.Read(bytes, 0, bytes.Length)) != 0) 
        { 

         // Translate data bytes to a ASCII string. 
         data = System.Text.Encoding.ASCII.GetString(bytes, 0, i); 
         Console.WriteLine("Received: {0}", data); 
         // etc.. 
         .... 

確定在客戶端上可以說,我要建立一個連接,然後通過流

      //Client 
      client = new TcpClient(serverIP, port); 

      // Get a client stream for reading and writing. 
      stream = client.GetStream(); 

      //then if I wish to send the string hello world to the server I would do: 
      sendString(stream, "Hello world"); 


    protected void sendString(NetworkStream stream, string str) 
    { 
     sendBytes(stream, textToBytes(str)); 
    } 

    protected void sendBytes(NetworkStream stream, Byte[] data) 
    { 
     // Send the message to the connected TcpServer. 
     stream.Write(data, 0, data.Length); 
    } 
    protected static Byte[] textToBytes(string text) 
    { 
     return System.Text.Encoding.ASCII.GetBytes(text); 
    } 

發送一些數據因爲我能夠發送字節,所以我可以發送文件或我想要的所有內容。我使用的技術是,如果我將字符串文件發送給服務器,則服務器將開始監聽文件。它將打開一個流並將接收到的字節寫入該文件。如果發送不同的關鍵字,則服務器將開始以不同的方法監聽等。

所以,當處理一臺服務器和一臺客戶端時,一切都很好。現在我想添加更多的客戶端並需要它們連接到服務器。我知道可以在同一個端口上建立多個連接,就像我們在網站上使用por 80一樣......我不知道如何管理多個連接。所以我想的一件事就是保持原樣。如果建立了連接,則通知服務器啓動另一個線程監聽同一端口上的其他連接。使用這種技術,我將有幾個線程運行,我只知道多線程的基本知識。如果這種技術是我最好的選擇,我將開始實施它。你們這些人對這一切都非常瞭解,所以如果有人能指引我正確的方向,那將會很好。或者,也許我應該聽幾個端口。例如,如果服務器已連接到端口7777,則不要接受來自該端口的連接,並開始監聽端口7778。我的意思是可能有很多不同的方式來實現我所需要的,你們可能知道最好的方法。我只知道網絡的基礎知識...

回答

1

你可以使用線程:

var client = server.AcceptTcpClient(); 
var t = new Thread(new ParameterizedThreadStart(AccentClient)); 
t.Start(client); 

目標的方法是這樣的

public void AccentClient(object clientObj) 
{ 
    var client = clientObj as TcpClient; 

    // Do whatever you need to do with the client 
} 

如果你不熟悉多線程,它是重要的是你至少要先學習基礎知識。

+0

「你可以嘗試」 - 你** **應該做......你應該異步BeginReceive方法使用盡量減少服務器回覆時間。 – Vlad

1

您可以實現封裝TCP行爲的類。檢查這個類:

public class SimpleListener 
{ 
    private System.Net.Sockets.TcpListener _tcpListen; 
    //declare delegate to handle new connections 
    public delegate void _new_client(System.Net.Sockets.TcpClient tcpclient); 

    //declare a clients container (or something like...). OPTION 1 
    List<System.Net.Sockets.TcpClient> _connected_clients; 

    //declare an event and event handler (the same for _new_client) for new connections OPTION 2 
    public event _new_client new_tcp_client; 



    //public (The list of connected clients). 
    public List<System.Net.Sockets.TcpClient> ConnectedClients { get { return _connected_clients; } } 


    public SimpleListener(string ip, int listenport) 
    { 
     System.Net.IPAddress ipAd = System.Net.IPAddress.Parse(ip); 
     _tcpListen = new System.Net.Sockets.TcpListener(new System.Net.IPEndPoint(ipAd,listenport)); 
     _connected_clients = new List<System.Net.Sockets.TcpClient>(); 
    } 

    //Fire this method to start listening... 
    public void Listen() 
    { 
     _tcpListen.Start(); 
     _set_listen(); 
    } 
    //... and this method to stop listener and release resources on listener 
    public void Stop() 
    { 
     _tcpListen.Stop(); 
    } 

    //This method set the socket on listening mode... 
    private void _set_listen() 
    { 
     //Let's do it asynchronously - Set the method callback, with the same definition as delegate _new_client 
     _tcpListen.BeginAcceptTcpClient(new AsyncCallback(_on_new_client), null); 
    } 



    //This is the callback for new clients 
    private void _on_new_client(IAsyncResult _async_client) 
    { 
     try 
     { 
      //Lets get the new client... 
      System.Net.Sockets.TcpClient _tcp_cl = _tcpListen.EndAcceptTcpClient(_async_client); 
      //Push the new client to the list 
      _connected_clients.Add(_tcp_cl); 
      //OPTION 2 : Fire new_tcp_client Event - Suscribers will do some stuff... 
      if (new_tcp_client != null) 
      { 
       new_tcp_client(_tcp_cl); 
      } 
      //Set socket on listening mode again... (and wait for new connections, while we can manage the new client connection) 
      _set_listen(); 
     } 
     catch (Exception ex) 
     { 
      //Do something...or not 
     } 
    } 

} 

你可以在你的代碼中使用此:

     //SERVER 
     // instantiate variables such as tempIp, port etc... 
     // ... 
     // ...  

     SimpleListener server = new SimpleListener(tempIp, port); //tempIp is the ip address of the server. 
     //add handler for new client connections 
     server.new_tcp_client += server_new_tcp_client; 
     // Start listening for client requests. 
     server.Listen(); 
     .... //No need to loop. The new connection is handled on server_new_tcp_client method 



    void server_new_tcp_client(System.Net.Sockets.TcpClient tcpclient) 
{ 
    // Buffer for reading data 
      Byte[] bytes = new Byte[MaxChunkSize]; 
      String data = null; 
      Console.WriteLine("Connected!"); 

       // Get a stream object for reading and writing 
      System.IO.Stream stream = tcpclient.GetStream(); 

       // now that the connection is established start listening though data 
       // sent through the stream.. 
       int i; 
       try 
       { 
        // Loop to receive all the data sent by the client. 
        while ((i = stream.Read(bytes, 0, bytes.Length)) != 0) 
        { 

         // Translate data bytes to a ASCII string. 
         data = System.Text.Encoding.ASCII.GetString(bytes, 0, i); 
         Console.WriteLine("Received: {0}", data); 
         // etc.. 
         .... 
}