我无法连接以测试使用 TcpListener 启动的本地服务器

Posted

技术标签:

【中文标题】我无法连接以测试使用 TcpListener 启动的本地服务器【英文标题】:I can't connect to test a local server started with TcpListener 【发布时间】:2016-02-23 16:07:35 【问题描述】:

免责声明:这是我第一次涉足与 tcp/socket 直接相关的任何事物。我已经阅读了 -the- -following- -resources- 并且正在尝试提出一个非常简单的测试应用程序。

我正在尝试开发一个使用 TcpListener 对象运行的本地服务器。我可以很好地实例化它并运行netstat 以查看处于 LISTENING 状态的端口。但是,我无法 telnet 或创建测试客户端来手动连接。 Telnet 简单地说它无法打开连接。尝试测试客户端应用程序会引发异常

System.dll 中出现“System.Net.Sockets.SocketException”类型的未处理异常

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

在this SO 问题中,提问者最终通过有故障的网卡解决了这个问题。我该如何寻找呢?

这让我很困惑。我如何测试或连接到服务器?这是我的代码。

对于服务器:

using System;
using System.Configuration;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;

namespace TcpConsole

    class Program
    
        static void Main(string[] args)
        
            var localPort = ConfigurationManager.AppSettings["localPort"];
            var portNumber = int.Parse(localPort);

            var maxConnections = ConfigurationManager.AppSettings["maxConnections"];
            var maxConnectionsNumber = int.Parse(maxConnections);

            Console.WriteLine("Preparing to start server on port 0", portNumber);
            Console.WriteLine("Max connections: 0", maxConnectionsNumber);

            var ipHostInfo = Dns.GetHostEntry("localhost");
            var ipAddress = ipHostInfo.AddressList[0];
            var localEndPoint = new IPEndPoint(ipAddress, portNumber);

            Console.WriteLine("Starting server with local IP 0", ipAddress);

            var listener = new TcpListener(localEndPoint);
            listener.Start(maxConnectionsNumber);

            Console.WriteLine();
            Console.WriteLine("Server started...");
            Console.WriteLine();
            
            while (true)
            
                var socket = listener.AcceptSocket();
                Task.Factory.StartNew(() =>
                
                    ProcessSocket(socket);
                );
            
        

        private static async void ProcessSocket(Socket socket)
        
            try
            
                using (var stream = new NetworkStream(socket))
                using (var reader = new StreamReader(stream))
                using (var writer = new StreamWriter(stream))
                
                    writer.AutoFlush = true;

                    var received = await reader.ReadToEndAsync();

                    Console.WriteLine("Received: " + received);
                

                socket.Close();
                socket.Dispose();
            
            catch (Exception exception)
            
                Console.WriteLine("There was an error processing a message.");
                Console.WriteLine(exception);
            
        
    

看到上面的代码在运行:

对于测试应用程序:

using System;
using System.IO;
using System.Net;
using System.Net.Sockets;

namespace TcpConsoleClient

    class Program
    
        static void Main(string[] args)
        
            var ipHostInfo = Dns.GetHostEntry("localhost");
            var ipAddress = ipHostInfo.AddressList[0];
            var remoteEndPoint = new IPEndPoint(ipAddress, 3245);

            var client = new TcpClient(remoteEndPoint);

            using (var stream = client.GetStream())
            using (var reader = new StreamReader(stream))
            using (var writer = new StreamWriter(stream))
            
                writer.AutoFlush = true;

                string input;

                while((input = Console.ReadLine()) != "exit")
                
                    writer.WriteLine(input);
                
            
        
    

【问题讨论】:

【参考方案1】:

TCP/IP 连接具有本地 IP 地址和端口,以及远程 IP 地址和端口。

通常,一个端口号一次只能分配给一个套接字。错误消息表明尝试将多个套接字与相同的端口号关联。

可以在客户端代码中找到原因:

var client = new TcpClient(remoteEndPoint);

TcpClient 构造函数的此重载接受指定 本地 端点的IPEndPoint。也就是说,当TcpClient 被构造时,它会被绑定到remoteEndPoint 指定的端口号,这会失败,因为该端口号已经被服务器应用程序使用了。

要解决此问题,请使用无参数 TcpClient 构造函数,并将 remoteEndPoint 传递给 Connect 调用:

var client = new TcpClient();

client.Connect(remoteEndPoint);

【讨论】:

以上是关于我无法连接以测试使用 TcpListener 启动的本地服务器的主要内容,如果未能解决你的问题,请参考以下文章

tcplistener 没有启动

为啥 TcpListener 会泄漏 ESTABLISHED 连接?

停止 TcpListener 的正确方法

如何获取 TcpListener 的公共端口号?

如何设置 TcpListener 始终监听并接受多个连接?

C# TcpListener如何知道客户端已经断开连接