当前位置:编程学习 > C#/ASP.NET >>

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;
        }
--------------------编程问答-------------------- 那就是原来的没有销毁呗 --------------------编程问答--------------------
引用 1 楼 u013096183 的回复:
那就是原来的没有销毁呗

在哪销毁?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#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,