[英]>1 client can't connect to server in c#
我正在C#中創建一個聊天客戶端,以在localhost上進行演示。
以下是相關代碼:
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,所以在這里不能使用ip,因為實例2,3和5也將具有相同的IP地址。 所以我想做的是用IP地址和PORT連接實例1和實例4,而不是像使用單個TCPListener那樣僅使用IP地址。
嘗試將這三行代碼移到start_listening例程的while(true)循環之外。
TcpListener listen = new TcpListener(IPAddress.Any, port_increment);
garabage_collection_preventor.Add(listen);
listen.Start();
您只需要一個偵聽器,即可從該偵聽器接受許多不同的連接。
像這樣嘗試:
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++;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.