IPAddress.Any
問題は、サーバーを構築するときに使用しているという事実にほぼ確実にあります。それが問題になる理由は、それが必ずしも解決されるとは限らないためlocalhost
です。幸運になるかもしれませんが、一貫性はありません。したがって、次のようなIPアドレスでサーバーを起動することをお勧めします。
var ipAddress = Dns.GetHostEntry("localhost").AddressList[0];
TcpListener server = new TcpListener(ipAddress, clientPort);
次に、これを行っていると確信していますが、ポートがとの両方clientPort
で同じであることを確認してくださいserverPort
。
次に、while (true)
ループは私には非常に疑わしいので、以下の例ではそれを変更します。不可能でない限り、常に避けてくださいwhile (true)
、あなたは文字通り問題を物乞いしています。
最後に、ここでスレッド化を行う方法を取り巻くと、どういうわけか2つの別々のスレッドを構築する必要があり、BackgroundWorker
クラスをお勧めします(他の人がお勧めするかもしれませんが、それについてはまだ十分にasync-await
わかりません。 .NET 4.5を使用する必要がありますが、使用しているかどうかはわかりません)。
したがって、BackgroundWorker
サーバー用に次のようなものを作成できます(そして、クライアント用に同様の別のものを作成できます)。
var worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.WorkerSupportsCancellation = true;
worker.ProgressChanged += (s, args) =>
{
Console.WriteLine(args.UserState);
}
worker.DoWork += (s, args) =>
{
// startup the server on localhost
var ipAddress = Dns.GetHostEntry("localhost").AddressList[0];
TcpListener server = new TcpListener(ipAddress, clientPort);
server.Start();
while (!worker.CancellationPending)
{
// as long as we're not pending a cancellation, let's keep accepting requests
TcpClient client = server.AcceptTcpClient();
StreamReader clientIn = new StreamReader(client.GetStream());
StreamWriter clientOut = new StreamWriter(client.GetStream());
clientOut.AutoFlush = true;
while ((string msg = clientIn.ReadLine()) != null)
{
worker.ReportProgress(1, msg); // this will fire the ProgressChanged event
clientOut.WriteLine(msg);
}
}
}
RunWorkerAsync
最後に、次のように呼び出すことで、これらのワーカーを起動する必要があります。
worker.RunWorkerAsync();
アップデート
了解しました。以下は、2104に接続する完全に機能するコンソールアプリケーションです。注意する必要があるのは、使用時にvar ipAddress = Dns.GetHostEntry("localhost").AddressList[0];
次のようなIPアドレスを取得することです。これ::1
が問題です。ただし、クライアントでリッスン127.0.0.1:2104
すると、を発行するときに接続しようとしているものがvar result = client.BeginConnect("localhost", 2104, null, null);
、を発行するのと同じであるため、接続できますnew TcpClient("localhost", 2104);
。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net.Sockets;
using System.ComponentModel;
using System.Threading;
using System.Net;
namespace ConsoleApplication13
{
class Program
{
static void Main()
{
var worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.WorkerSupportsCancellation = true;
worker.ProgressChanged += (s, args) =>
{
Console.WriteLine(args.UserState);
};
worker.DoWork += (s, args) =>
{
// startup the server on localhost
var ipAddress = IPAddress.Parse("127.0.0.1");
TcpListener server = new TcpListener(ipAddress, 2104);
server.Start();
while (!worker.CancellationPending)
{
Console.WriteLine("The server is waiting on {0}:2104...", ipAddress.ToString());
// as long as we're not pending a cancellation, let's keep accepting requests
TcpClient attachedClient = server.AcceptTcpClient();
StreamReader clientIn = new StreamReader(attachedClient.GetStream());
StreamWriter clientOut = new StreamWriter(attachedClient.GetStream());
clientOut.AutoFlush = true;
string msg;
while ((msg = clientIn.ReadLine()) != null)
{
Console.WriteLine("The server received: {0}", msg);
clientOut.WriteLine(string.Format("The server replied with: {0}", msg));
}
}
};
worker.RunWorkerAsync();
Console.WriteLine("Attempting to establish a connection to the server...");
TcpClient client = new TcpClient();
for (int i = 0; i < 3; i++)
{
var result = client.BeginConnect("localhost", 2104, null, null);
// give the client 5 seconds to connect
result.AsyncWaitHandle.WaitOne(5000);
if (!client.Connected)
{
try { client.EndConnect(result); }
catch (SocketException) { }
string message = "There was an error connecting to the server ... {0}";
if (i == 2) { Console.WriteLine(message, "aborting"); }
else { Console.WriteLine(message, "retrying"); }
continue;
}
break;
}
if (client.Connected)
{
Console.WriteLine("The client is connected to the server...");
StreamReader clientIn = new StreamReader(client.GetStream());
StreamWriter clientOut = new StreamWriter(client.GetStream());
clientOut.AutoFlush = true;
string key;
while ((key = Console.ReadLine()) != string.Empty)
{
clientOut.WriteLine(key);
Console.WriteLine(clientIn.ReadLine());
}
}
else { Console.ReadKey(); }
}
}
}