C#TCP客户端无法连接
我创建了一个与局域网中其他计算机连接的类。当我第一次导出一个方法Connect时,一切都正常,但是在工作类之后,变量失去了对这个对象的引用 但是,如果我再次尝试创建此对象,并引入一个方法Connect,则会出现一个错误,即“只允许使用每个套接字地址(协议/网络地址/端口)的一个” 这个错误是在我尝试执行以下操作时发生的C#TCP客户端无法连接,c#,tcpclient,C#,Tcpclient,我创建了一个与局域网中其他计算机连接的类。当我第一次导出一个方法Connect时,一切都正常,但是在工作类之后,变量失去了对这个对象的引用 但是,如果我再次尝试创建此对象,并引入一个方法Connect,则会出现一个错误,即“只允许使用每个套接字地址(协议/网络地址/端口)的一个” 这个错误是在我尝试执行以下操作时发生的 partner.Connect(partnerIPEndPoint) 我班上什么不好?如果有人能帮助我,我将不胜感激。 提前谢谢 这是我的班级: using System; us
partner.Connect(partnerIPEndPoint)代码>
我班上什么不好?如果有人能帮助我,我将不胜感激。
提前谢谢
这是我的班级:
using System;
using System.Net;
using System.Net.Sockets;
using System.Diagnostics;
namespace AudioNetwork
{
class ConnectToServer : IDisposable
{
public int BeepAmonut { get; set; }
public int Speed { get; set; }
public IPAddress MyIPAddress { get; set; }
public IPAddress PartnerIPAddress { get; set; }
private NetworkStream stream;
private TcpClient partner;
public void Connect()
{
IPEndPoint myIPEndPoint = new IPEndPoint(MyIPAddress, 800);
IPEndPoint partnerIPEndPoint = new IPEndPoint(PartnerIPAddress, 800);
partner = new TcpClient(myIPEndPoint);
partner.Connect(partnerIPEndPoint);
stream = partner.GetStream();
Messanger(stream);
}
protected virtual void Messanger(NetworkStream myStream)
{
byte[] data = { 2, 1 };
myStream.Write(data, 0, data.Length);
Play(2000);
}
public void Play(int time)
{
Stopwatch sw = new Stopwatch();
sw.Start();
while (sw.ElapsedMilliseconds <= 2100)
{
if (sw.ElapsedMilliseconds >= time)
{
break;
}
}
}
public void Dispose()
{
GC.SuppressFinalize(this);
stream.Dispose();
stream.Close();
partner.Client.Dispose();
partner.Close();
}
}
class ConnectToClient : ConnectToServer
{
protected override void Messanger(NetworkStream myStream)
{
byte[] data = new byte[256];
int bytes = myStream.Read(data, 0, data.Length);
if (data[0] == 2)
{
Play(1980);
}
}
}
}
使用系统;
Net系统;
使用System.Net.Sockets;
使用系统诊断;
名称空间音频网络
{
类ConnectToServer:IDisposable
{
public int BeepAmonut{get;set;}
公共整数速度{get;set;}
公共IPAddress MyIPAddress{get;set;}
公共IPAddress PartnerIPAddress{get;set;}
专用网络流;
私人TCP客户合作伙伴;
公共void Connect()
{
IPEndPoint myIPEndPoint=新IPEndPoint(MyIPAddress,800);
IPEndPoint partnerIPEndPoint=新IPEndPoint(PartnerIPAddress,800);
合作伙伴=新的TCP客户(myIPEndPoint);
partner.Connect(partnerIPEndPoint);
stream=partner.GetStream();
Messanger(溪流);
}
受保护的虚拟void Messanger(NetworkStream myStream)
{
字节[]数据={2,1};
Write(data,0,data.Length);
Play(2000年);
}
公共无效播放(整数时间)
{
秒表sw=新秒表();
sw.Start();
同时(sw.ElapsedMilliseconds=时间)
{
打破
}
}
}
公共空间处置()
{
总干事(本);
stream.Dispose();
stream.Close();
partner.Client.Dispose();
partner.Close();
}
}
类ConnectToClient:ConnectToServer
{
受保护的覆盖无效消息(NetworkStream myStream)
{
字节[]数据=新字节[256];
int bytes=myStream.Read(data,0,data.Length);
如果(数据[0]==2)
{
戏剧(1980);
}
}
}
}
将硬编码端口分配给本地端点,但不关闭它
- 打开第一个连接时,端口800上的本地套接字已连接到端口800上的远程套接字
- 然后忘记关闭此连接(因为您从未在
steam
或partner
上调用Dispose
-我看不到您的Dispose
函数在任何地方被调用)
- 当您试图在本地端口800上打开第二个连接时,它已经被第一个连接占用,这将导致您遇到的错误
解决方案是让操作系统为本地套接字分配一个自动端口号。这样:
- 打开第一个连接时,自动分配的端口号上有一个本地套接字连接到端口800处的远程套接字
- 当您打开第二个连接时,即使第一个连接尚未关闭,操作系统也会为第二个套接字分配不同的端口号,并将其连接到端口800处的远程套接字
在代码中,这很简单:
partner = new TcpClient();
然后扔掉所有的MyIPAddress
东西。我调用了Dispose();来自其他代码。Dispose方法在我的类中。即使关闭套接字,操作系统也可能需要几秒钟才能识别套接字已关闭。如果需要使用相同的端口,那么您唯一的选择就是等待套接字被回收。您不需要删除MyIPAddress内容,特别是如果您的计算机上有各种接口,并且需要使用特定的接口。如果排除它,它将默认为OS的默认接口。考虑使用IP端点MyIPEnPosit=新IP端点(MyIPAdt,0);相反指定0将自动分配端口号。@这将有助于说明多个接口。但我假设这里的设置更为传统,因为问题是关于网络基础的。