c#网络编程报错"通常每个套接字地址(协议/网络地址/端口)史允许使用一次"
说细描述:程序在最开始启动监听都可以正常运行,但是当点击停止监听,再次启动监听时就报错 “通常每个套接字地址(协议/网络地址/端口)史允许使用一次",主要代码如下:Thread myThread;
private void buttonStart_Click(object sender, EventArgs e)
{
//由于服务器要为多个客户服务,所以需要创建一个线程监听客户端连接请求
try
{
ThreadStart ts = new ThreadStart(AcceptConnect);
myThread = new Thread(ts);
myThread.Start();
buttonStart.Enabled = false;
buttonStop.Enabled = true;
}
catch(Exception Ex)
{
listBoxStatus.Invoke(setListBoxCallBack, Ex.Message);
}
}
private void AcceptConnect()
{
//获取本机所有IP地址
try
{
IPAddress[] ip = Dns.GetHostAddresses("192.168.0.35");
listener = new TcpListener(ip[0], 51888);
listener.Start(); //开始侦听传入的连接请求
while (isExit == false)
{
try
{
//将事件的状态设为非终止
allDone.Reset();
//引用在异步操作完成时调用的回调方法
AsyncCallback callback = new AsyncCallback(AcceptTcpClientCallback);
listBoxStatus.Invoke(setListBoxCallBack, "开始等待客户连接");
//开始一个异步操作接受传入的连接尝试
listener.BeginAcceptTcpClient(callback, listener);
//阻塞当前线程,直到收到客户连接信号
allDone.WaitOne();
}
catch (Exception Err)
{
listBoxStatus.Invoke(setListBoxCallBack, Err.Message);
}
}
}
catch(Exception Ex)
{
listBoxStatus.Invoke(setListBoxCallBack, Ex.Message);
}
}
//ar是IAsyncResult类型的接口,表示异步操作的状态
private void AcceptTcpClientCallback(IAsyncResult ar)
{
try
{
//将事件状态设为终止状态,允许一个或多个等待线程继续
allDone.Set();
TcpListener myListener = (TcpListener)ar.AsyncState;
//异步接受收传入的连接,并创建新的TcpClient对象处理远程主机通讯
TcpClient client = myListener.EndAcceptTcpClient(ar);
listBoxStatus.Invoke(setListBoxCallBack, "已接受客户连接:" + client.Client.RemoteEndPoint);
comboBox1.Invoke(setComboBoxCallBack, client.Client.RemoteEndPoint.ToString());
ReadWriteObject readWriteObject = new ReadWriteObject(client);
clientList.Add(readWriteObject);
SendString(readWriteObject, "服务器已经接受连接,请通话!");
readWriteObject.netStream.BeginRead(readWriteObject.readBytes, 0, readWriteObject.readBytes.Length, ReadCallback, readWriteObject);
}
catch(Exception Err)
{
listBoxStatus.Invoke(setListBoxCallBack, Err.Message);
return;
}
}
//停止监听
private void buttonStop_Click(object sender, EventArgs e)
{
//使线程自动结束
isExit = true;
// listener.Stop();
//将事件状态设置为终止状态,允许一个或多个等待线程继续
//从而使线程正常结束
allDone.Set();
buttonStart.Enabled = true;
buttonStop.Enabled = false;
}
--------------------编程问答-------------------- 那就是原来的没有销毁呗 --------------------编程问答--------------------
在哪销毁?listener.Stop();将监听停止也报错 --------------------编程问答-------------------- 目测 端口被占用 --------------------编程问答-------------------- 楼主你写的监听逻辑有问题,
你是用的异步监听,没必要用线程去跑。
点击启动的时候执行
IPAddress[] ip = Dns.GetHostAddresses("192.168.0.35");
listener = new TcpListener(ip[0], 51888);
listener.Start();
listener.BeginAcceptTcpClient(callback, listener);
然后在AcceptTcpClientCallback方法里最后在加上listener.BeginAcceptTcpClient(callback, listener);
这样就实现循环监听了。
改成这样之后你在listener.Stop();就不会报错了
你这里用的线程同步完全是多余的,自己把简单问题复杂化了。 --------------------编程问答-------------------- 没有看你的代码。单就你的标题来看,这种东西通常都会在“重复启动”一个操作时(例如放在按钮事件处理下)出现。当你绑定一个端口时,应该先把之前的shutdown和close掉。或者就应该使用if判断来避免重复绑定同一个端口。 --------------------编程问答-------------------- 代码有问题,步骤明显的重复和啰嗦
补充:.NET技术 , C#