几乎可以肯定,问题在于您IPAddress.Any
在构建服务器时使用的事实。这是一个问题的原因是因为这不一定会解决localhost
,尽管你可能很幸运,但它并不一致。因此,我建议使用如下 IP 地址启动服务器:
var ipAddress = Dns.GetHostEntry("localhost").AddressList[0];
TcpListener server = new TcpListener(ipAddress, clientPort);
接下来,尽管我确信您正在执行此操作,但请确保 和 的端口clientPort
相同serverPort
。
接下来,while (true)
循环对我来说非常可疑,因此在下面的示例中,我将对其进行更改。除非不可能总是避免while (true)
,否则你实际上是在乞求一个问题。
最后,围绕你将如何在这里进行线程化,你将需要以某种方式构建两个单独的线程,我将推荐该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:
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(); }
}
}
}