如何修复错误“每个套接字地址(协议/网络地址/端口)通常只允许使用一次”?

Posted

技术标签:

【中文标题】如何修复错误“每个套接字地址(协议/网络地址/端口)通常只允许使用一次”?【英文标题】:How do I fix the error "Only one usage of each socket address (protocol/network address/port) is normally permitted"? 【发布时间】:2013-01-17 06:41:38 【问题描述】:

我进行了很多谷歌搜索,但对我的问题并不满意。我是网络编程的新手并正在尝试学习,我尝试设置一个简单的服务器和客户端进行通信(遵循位于此处的在线教程-> http://tech.pro/tutorial/704/csharp-tutorial-simple-threaded-tcp-server)

我遇到的问题是,当尝试在服务器上启动 TcpListener 时,我不断收到异常“每个套接字地址(协议/网络地址/端口)通常只允许使用一次”。

我尝试禁用我的防火墙,更改要使用的端口,移动变量但无济于事(客户端工作正常,但它显然找不到服务器,因为我无法启动它)。

我见过描述使用 Socket.Poll() 的解决方案,但由于我只使用 TcpListener 对象,我不知道如何使用 Poll 函数。

我的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Text;

namespace ServerTutorial 
class Server 
    private readonly Thread m_listenThread;

    public Server() 
        m_listenThread = new Thread(new ThreadStart(ListenForClients));
        m_listenThread.Start();
    

    public void ListenForClients() 
        var listener = new TcpListener(IPAddress.Any, 3000);
        listener.Start();

        while (true) 
            //Blocks until a client has connected to the server
            TcpClient client = listener.AcceptTcpClient();

            //Send a message to the client
            var encoder = new ASCIIEncoding();
            NetworkStream clientStream = client.GetStream();
            byte[] buffer = encoder.GetBytes("Hello Client!");
            clientStream.Write(buffer, 0, buffer.Length);
            clientStream.Flush();

            //Create a thread to handle communication with the connected client
            var clientThread = new Thread(new ParameterizedThreadStart(HandleClient));
            clientThread.Start(client);
        
    

    private void HandleClient(object clientObj)  //Param thread start can only accept object types, hence the cast
        var client = (TcpClient) clientObj;
        NetworkStream clientStream = client.GetStream();

        var message = new byte[4096];

        while (true) 
            int bytesRead = 0;

            try 
                //Block until a client sends a message
                bytesRead = clientStream.Read(message, 0, 4096);
             catch 
                //A socket error has occurred
                System.Diagnostics.Debug.WriteLine("A socket error has occured");
                break;
            

            if (bytesRead == 0) 
                //The client has disconnected from the server
                System.Diagnostics.Debug.WriteLine("A client has disconnected from the server");
                client.Close();
                break;
            

            //Message has been received
            var encoder = new ASCIIEncoding();
            System.Diagnostics.Debug.WriteLine(encoder.GetString(message, 0, bytesRead));
        
    


在我的主要方法中:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ServerTutorial 
class Program 
    static void Main(string[] args) 
        var server = new Server();
        server.ListenForClients();
    


非常感谢任何帮助!

【问题讨论】:

注意mingw-w64 你需要closesocket() 而不是close() 来释放端口。 【参考方案1】:

ListenForClients 被调用两次(在两个不同的线程上)- 一次来自构造函数,一次来自Main 中的显式方法调用。当TcpListener 的两个实例尝试侦听同一端口时,您会收到该错误。

【讨论】:

+1 这也解释了为什么您在更改端口号时仍然出现错误 非常感谢!有时很容易忽视这样的愚蠢事情! :D 当您尝试再次绑定套接字服务器时也会发生这种情况,即使 IsBound == false。尝试设置 SOKEEPALIVE = false;【参考方案2】:

您正在调试两次或多次。因此应用程序可能一次运行更多。那么只会出现这个问题。您应该使用任务管理器关闭所有调试应用程序,然后再次调试。

【讨论】:

【参考方案3】:

我在 windows server 2012 STD 64 位上遇到了类似的问题,在使用所有可用的 windows 更新更新 windows 后我的问题得到解决。

【讨论】:

以上是关于如何修复错误“每个套接字地址(协议/网络地址/端口)通常只允许使用一次”?的主要内容,如果未能解决你的问题,请参考以下文章

无法绑定地址 [10048]:每个套接字地址(协议/网络地址/端口)通常只允许使用一次

Windows socket error: 通常每个套接字地址(协议/网络地址/端口)只允许使用一次.(10048)

每个套接字地址(协议/网络地址/端口)通常只允许使用一次?

(OS 10048) 每个套接字地址(协议/网络地址/端口)通常只允许使用一次。视窗阿帕奇

HttpClient:每个套接字地址(协议/网络地址/端口)通常只允许使用一次

WCF:System.Net.SocketException - 每个套接字地址(协议/网络地址/端口)通常只允许使用一次