2012-11-20 163 views
1

我正在C#中創建一個聊天客戶端在本地主機上進行演示。> 1客戶端無法連接到服務器在c#

下面是相關代碼:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Net.Sockets; 
using System.Net; 
using System.IO; 
using System.Threading; 

namespace WindowsFormsApplication1 
{ 
public partial class Form1 : Form 
{ 
    static List<TcpListener> garabage_collection_preventor = new List<TcpListener>(); 
    static Dictionary<IPEndPoint, bool> address_dictionary = new Dictionary<IPEndPoint, bool>(); 
    static int port_increment = 9999; 
    static int client_id = 0; 

    void start_listening() 
    { 
     while (true) 
     { 
      TcpListener listen = new TcpListener(IPAddress.Any, port_increment); 
      garabage_collection_preventor.Add(listen); 
      listen.Start(); 
      TcpClient client = listen.AcceptTcpClient(); 
      IPEndPoint temp_end = ((IPEndPoint)listen.LocalEndpoint); 
      address_dictionary.Add(temp_end, false); 
      port_increment++; 
      new Thread(new ParameterizedThreadStart(connection_stuff)).Start(client); 
     } 
    } 

    void writer(object ob,int end_point) 
    { 
     StreamWriter write = ob as StreamWriter; 
     while (true) 
     { 
      foreach (KeyValuePair<IPEndPoint, bool> value in address_dictionary) 
      { 
       IPEndPoint index = value.Key; 
       int temp = value.Key.Port; 
       if (temp == end_point) 
       { 
        while (address_dictionary[index] == true) 
        { 
         write.WriteLine(msg_box.Text); 
        } 
       } 
      } 
     } 
    } 

    void reader(StreamReader read) 
    { 
     while (true) 
     { 
      MessageBox.Show(read.ReadLine()); 
     } 
    } 

    void connection_stuff(object ob) 
    { 
     TcpClient client = ob as TcpClient; 
     int writer_identification_endpoint = ((IPEndPoint)client.Client.LocalEndPoint).Port; 

     NetworkStream stream = client.GetStream(); 
     StreamReader read = new StreamReader(stream); 
     StreamWriter write = new StreamWriter(stream); 

     ThreadStart port_passing = delegate { writer(write, writer_identification_endpoint); }; 
     Thread thread = new Thread(port_passing); 

     reader(read); 
     thread.Start(); 
    } 

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void send_Click(object sender, EventArgs e) 
    { 
     int end_point = int.Parse(port.Text); 
     foreach (KeyValuePair<IPEndPoint, bool> value in address_dictionary) 
     { 
      IPEndPoint index = value.Key; 
      int temp = value.Key.Port; 
      if (temp == end_point) 
      { 
       address_dictionary[index] = true; 
      } 
     } 
    } 

    private void listener_Click(object sender, EventArgs e) 
    { 
     new Thread(start_listening).Start(); 
     listener.Enabled = false; 
    } 
} 
} 

現在的問題是,第一個客戶端可以方便地與程序連接,併發送該程序可以輕鬆讀取信息。但是,每個後續客戶端都無法連接。

我知道我不應該創建超過一個TCPListener,但問題是我必須演示本地主機上的程序和端口號是區分客戶端的唯一真實方法。

所以請告訴我我的頭撞牆上的代碼有什麼問題幾個小時。

編輯

這是當英語不是:)此代碼(不是目前完成)第一語言發生了什麼將是一個聊天客戶端。此代碼的每個實例都能夠與此相同代碼的其他實例進行通信。任何數量的實例都應該能夠連接任意數量的實例(例如,如果雙擊5次程序,現在將有5個實例可以彼此通信)。

現在的問題是,每個實例將具有相同的IP地址(因爲它們都運行在同一臺計算機上)。問題出現在實例1假設連接到實例4時,因爲實例2,3和5也具有相同的IP地址,所以在這裏不能使用ip。所以我想要做的是將實例1與實例4連接到IP地址和端口,而不是像使用單個TCPListener那樣只使用IP地址。

+0

可能重複(http://stackoverflow.com/questions/13404803/tcplistener-tcpclient-stops-processing-data-under-certain-circumstances) –

回答

5

嘗試在start_listening例程的while(true)循環之外移動這三行代碼。

TcpListener listen = new TcpListener(IPAddress.Any, port_increment); 
garabage_collection_preventor.Add(listen); 
listen.Start(); 

您只需要一個偵聽器,您可以從中接受許多不同的連接。

+0

正如我在我的帖子中所說,我不能讓單個TCP偵聽器。由於程序將在本地主機上運行要求我必須使多個TCPlistener能夠根據端口監聽客戶端,而不是基於IP(因爲本地主機上的所有客戶端都具有相同的地址)。任何其他建議。 –

+1

@WinCoder你的概念不正確。監聽單個端口的單個監聽程序可以像許多客戶端一樣使用它。唯一的區別是它是在一個循環(迭代服務器)中執行還是爲每個客戶端創建一個新的線程/進程(併發)。每次接聽電話後,您都會獲得一個與特定客戶端連接的新套接字。每個客戶端都有自己的源IP和端口,連接的監聽器響應該源IP和端口。簡單的例如是谷歌網頁服務器,所有客戶端連接到它在80端口,它以最好的方式處理它們。 – fayyazkl

+0

正如我已經說過無數次,這不是一個真正的世界程序,它只能在本地主機上工作,其中該程序的所有實例將具有相同的IP。因此,我不能在同一端口上監聽所有客戶端,因爲那樣我就無法區分它們(因爲它們都具有相同的IP,而不像所有客戶端都具有唯一IP的Web服務器)。無論如何,這個問題已不再相關,因爲我自己解決了我的問題。 –

0

試試這樣說:

void start_listening() 
{ 
    TcpListener listen = new TcpListener(IPAddress.Any, port_increment); 
    garabage_collection_preventor.Add(listen); 
    listen.Start(); 
    while (true) 
    { 
     TcpClient client = listen.AcceptTcpClient(); 
     // etc 
    } 
} 

也就是說,一旦你已經創建了監聽器,它運行在循環接受來自客戶端的傳入連接。

編輯:你遇到的問題是因爲你的模擬有缺陷。在現實世界中,每個聊天服務器都運行在一個O/S實例上,位於一個已知的端口號上。由於您自己只有一個O/S實例,因此您無法在該實例上運行多個聊天服務器,並且都在相同的端口上偵聽。但是像這樣的東西可能會奏效,也就是說,您需要兩個循環,第一個創建監聽器,第二個內部循環讓每個監聽器接受多個客戶端。注意:這些循環需要退出條件!

void start_listening() 
{ 
    while (true) 
    { 
     TcpListener listen = new TcpListener(IPAddress.Any, port_increment); 
     garabage_collection_preventor.Add(listen); 
     listen.Start(); 
     while (true) 
     { 
      TcpClient client = listen.AcceptTcpClient(); 
      IPEndPoint temp_end = ((IPEndPoint)listen.LocalEndpoint); 
      address_dictionary.Add(temp_end, false); 
      new Thread(new ParameterizedThreadStart(connection_stuff)).Start(client); 
     } 
     port_increment++; 
    } 
} 
的[的TcpListener/TcpClient的停止在某些情況下處理數據]
+0

我的程序將在本地主機上運行,​​多個客戶端將相互連接。由於所有的客戶端都具有相同的IP,因此唯一可區分的角色將是他們連接的端口。單個TCPListener的問題是它只會監視一個端口。所以我不能使用單個TCPListener解決方案。請有任何其他方式 –

相關問題