2012-11-20 160 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解决方案。请有任何其他方式 –

相关问题