ローカルホストでデモを行うために、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;
}
}
}
ここでの問題は、最初のクライアントがプログラムに簡単に接続して、このプログラムが簡単に読み取れるメッセージを送信できることです。ただし、後続のすべてのクライアントは接続できません。
私は 1 つ以上の TCPListener を作成するべきではないことを知っていますが、問題は、ローカルホストでプログラムを実証する必要があり、ポート番号がクライアントを区別する唯一の真の方法であることです。
ですから、私が何時間も壁に頭をぶつけてきたコードの何が問題なのか教えてください。
編集
これは、英語が第一言語でない場合に起こることです:) このコード(現在は完全ではありません)はチャットクライアントになります。このコードの各インスタンスは、この同じコードの他のインスタンスと接続して通信できます。任意の数のインスタンスが任意の数のインスタンスと接続できる必要があります (たとえば、プログラムを 5 回ダブルクリックすると、5 つのインスタンスが相互に通信できるようになります)。
ここでの問題は、すべてのインスタンスが同じ IP アドレスを持つことです (それらはすべて同じマシンで実行されているため)。インスタンス 1 がインスタンス 4 に接続すると仮定すると、インスタンス 2、3、および 5 も同じ IP アドレスを持つため、ここでは ip を使用できません。したがって、私がやろうとしているのは、単一の TCPListener の場合のように IP アドレスだけを使用するのではなく、インスタンス 1 とインスタンス 4 を IP アドレスと PORT で接続することです。