我写了一个程序来与TcpListener和TcpClient进行通信。程序可以是接收方或发送方。接收方使用 TcpListener/TcpClient 的顺序类似于发送方的顺序。
在我编写代码的Windows 10机器上,代码工作正常,但在Windows 7机器上,代码不起作用。
我从发件人那里收到以下错误:无法建立连接,因为目标计算机主动拒绝了它 127.0.0.1:8000。
那么这个问题的原因是什么呢?这是否与计算机的速度有关,因为W10机器有i7,而W7有较旧的i5?
这是发件人代码:
private void sendingThreadFunction()
{
try
{
using (ECDiffieHellmanCng sendingMode = new ECDiffieHellmanCng())
{
using (TextReader reader = File.OpenText("sendersReceivingPort.txt"))
{
sendersReceivingPort = int.Parse(reader.ReadLine());
sendersReceivingPort++;
}
using (StreamWriter sw = new StreamWriter("sendersReceivingPort.txt"))
{
sw.WriteLine(sendersReceivingPort.ToString());
}
sendingMode.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
sendingMode.HashAlgorithm = CngAlgorithm.Sha256;
sendersPublicKey = sendingMode.PublicKey.ToByteArray();
IPEndPoint ipLocalEndPoint = new IPEndPoint(IPAddress.Parse(ipAddress), sendersReceivingPort);
sendingSendPublicKeyNotification = new TcpClient(ipLocalEndPoint);
sendingSendPublicKeyNotification.Connect(IPAddress.Parse(ipAddress), receiversReceivingPort);
NetworkStream dataStreamNotification = sendingSendPublicKeyNotification.GetStream();
byte[] notification = Encoding.UTF8.GetBytes("#PK");
dataStreamNotification.Write(notification, 0, notification.Length);
dataStreamNotification.Close();
sendingSendPublicKeyNotification.Close();
Thread.Sleep(400);
sendingPublicKey = new TcpClient();
sendingPublicKey.Connect(IPAddress.Parse(ipAddress), receiversReceivingPort);
NetworkStream dataStreamPublicKey = sendingPublicKey.GetStream();
dataStreamPublicKey.Write(sendersPublicKey, 0, sendersPublicKey.Length);
dataStreamPublicKey.Close();
sendingPublicKey.Close(); //poslje public key
Thread.Sleep(400);
sendingReceivePublicKeyListener = new TcpListener(IPAddress.Parse(ipAddress), sendersReceivingPort);
sendingReceivePublicKeyListener.Start();
sendingReceivePublicKeyNotificationClient = sendingReceivePublicKeyListener.AcceptTcpClient();
NetworkStream dataStreamReceivedNotification = sendingReceivePublicKeyNotificationClient.GetStream();
byte[] notificationReceived = new byte[3];
dataStreamReceivedNotification.Read(notificationReceived, 0, notificationReceived.Length);
dataStreamReceivedNotification.Close();
sendingReceivePublicKeyListener.Stop();
if(Encoding.UTF8.GetString(notificationReceived) != "#PK")
{
senderMode.Join();
}
sendersListener = new TcpListener(IPAddress.Parse(ipAddress), sendersReceivingPort);
sendersListener.Start();
sendersNewClient = sendersListener.AcceptTcpClient();
NetworkStream dataStreamReceive = sendersNewClient.GetStream();
byte[] receiversPublicKey = new byte[1024];
dataStreamReceive.Read(receiversPublicKey, 0, receiversPublicKey.Length);
dataStreamReceive.Close();
receiversPublicKey = Decode(receiversPublicKey);
sendersListener.Stop(); //prejmemo prejemnikov public key
CngKey secretKey = CngKey.Import(receiversPublicKey, CngKeyBlobFormat.EccPublicBlob);
sendersKey = sendingMode.DeriveKeyMaterial(CngKey.Import(receiversPublicKey, CngKeyBlobFormat.EccPublicBlob));
byte[] encryptedFile = null;
byte[] ivFile = null;
byte[] fileBytes = File.ReadAllBytes(fileToSendPath);
Encryption(sendersKey, fileBytes, out encryptedFile, out ivFile);
byte[] encryptedFD = null;
byte[] ivFD = null;
byte[] fdInformation = Encoding.UTF8.GetBytes("#FD|" + fileToSendName + "|" + encryptedFile.Length.ToString());
Encryption(sendersKey, fdInformation, out encryptedFD, out ivFD); // kriptira podatke o datoteki
sendingFD = new TcpClient();
sendingFD.Connect(IPAddress.Parse(ipAddress), receiversReceivingPort);
NetworkStream dataStreamFD = sendingFD.GetStream();
var mergedFDData = new byte[ivFD.Length + encryptedFD.Length];
ivFD.CopyTo(mergedFDData, 0);
encryptedFD.CopyTo(mergedFDData, ivFD.Length);
dataStreamFD.Write(mergedFDData, 0, mergedFDData.Length);
dataStreamFD.Close();
sendingFD.Close();
Thread.Sleep(400);
sendingFile = new TcpClient();
sendingFile.Connect(IPAddress.Parse(ipAddress), receiversReceivingPort);
NetworkStream dataStreamFile = sendingFile.GetStream();
var mergedFileData = new byte[ivFile.Length + encryptedFile.Length];
ivFile.CopyTo(mergedFileData, 0);
encryptedFile.CopyTo(mergedFileData, ivFile.Length);
dataStreamFile.Write(mergedFileData, 0, mergedFileData.Length);
dataStreamFile.Close();
sendingFile.Close(); //poslje file
}
} catch(Exception e)
{
MessageBox.Show("Sender - " + e.Message);
senderMode.Join();
}
senderMode.Join();
}
我对 C# 一无所知,但我怀疑它与您的计算机硬件有关。我会检查以下两件事:
-
是否有任何程序已经在您的 Windows 7 机器上运行并侦听端口 8000 ?可以是网络服务器,游戏,任何第三方软件。甚至是已经在运行的旧版本的程序。尝试重新启动计算机并再次检查。
-
您的Windows机器上是否正在运行任何防火墙?可能是 Windows 防火墙或防病毒程序安装的防火墙。
*编辑 刚刚注意到您在上面的评论TIMED_WAIT表明端口正在使用中。
它将是:A,Windows防火墙,转到defender并将其关闭以测试它是否有效,如果确实有效,您可以添加例外并将其重新打开。B,端口正在使用中。
快速搜索显示,使用:
IPEndPoint ipLocalEndPoint = new IPEndPoint(IPAddress.Loopback, sendersReceivingPort);
将在本地主机上使用防火墙(至少用于测试目的),您正在打开计算机,因此您可以理解,您必须明确告诉您的防火墙您要打开网络!
>端口 8000 很可能被另一个程序使用。特别是如果它在一台计算机上工作但在另一台计算机上主动拒绝(一台计算机可能安装了另一台没有安装的程序)。尝试另一个端口(例如 25568)