TcpListener和TcpClient共享本地端口

本文关键字:共享 TcpClient TcpListener | 更新日期: 2023-09-27 18:30:06

我在不同的机器上有两个相同应用程序的实例,它们应该相互通信,其中没有一个是典型的服务器或客户端。

应用程序的两个实例都有一个TcpListener,本地端口=8000。

一个应用程序实例(称之为"A")创建了一个TcpClient。现在,该客户端不能具有本地端口=8000,或者构造函数抛出套接字异常"通常只允许使用每个套接字地址(协议/网络地址/端口)一次"

因此,我创建了第一个具有随机本地端口的客户端,并运行Connect()来连接其他应用程序实例"B"。

"B"使用TcpListener.AcceptTcpClient()接受连接,它返回一个可用于与"a"通信的TcpClient。不过,这个TcpClient与TcpListener具有相同的IP和端口当我在"A"上手动创建TcpClient时,不能使用同一个端口,这怎么可能?实际上,我真的希望他们在两台机器上使用与侦听器相同的端口。。。

那么,如何在"A"上创建与TcpListener具有相同端口的TcpClient呢?

TcpListener和TcpClient共享本地端口

我认为您可能不完全理解地址端口客户端-服务器体系结构。

TcpListener正在侦听地址和端口上的任何连接。建立连接后,您可以使用"套接字"接收和发送来自客户端和服务器的消息。

示例:

0.0.0.1是机器A。

0.0.0.2是机器B。

您可以在机器a上的端口8000上放置一个正在侦听的TcpListener。当机器B上的TcpClient尝试连接端口8000上的机器a时,机器B上将获得一个生成的(由操作系统)端口。

然后你会有一个连接

0.0.0.1:8000->0.0.0.2:3587(生成的端口)-所以您不需要担心客户端侦听端口。

TCP连接总是有一个服务器端和一个客户端。服务器正在侦听(等待)连接,客户端连接到服务器。

当服务器收到连接请求时,AcceptTcpClient会为您提供服务器端的套接字,以便与客户端通信。TCP连接始终由双方的IP地址和端口定义:serverip:serverport和clientip:clientport。

如果您想要一个真正对称的系统,那么两个实例都将有一个服务器和一个连接到另一个服务器的客户端。然后,所有数据将始终通过客户端建立的连接从客户端发送到服务器。

例如:

ClientA connects to ServerB -> ConnectionAB
ClientB connects to ServerA -> ConnectionBA
ApplicationA sends data to ApplicationB over ConnectionAB
ApplicationB sends data to ApplicationA over ConnectionBA

如果您的目标是使用两个TCP端点相互通信,而其中一个端点不是显式服务器,您可能应该运行一个侦听器(在您的情况下,在端口8000上)在两台机器上。接下来,让每台机器随机尝试连接——让每台机器选择一个随机时间(在0和T之间),然后醒来。无论哪台机器首先唤醒,将调用connect()并建立连接。

正如@nivpenso所指出的,进行连接的端点不需要显式绑定到一个端口。connect()步骤显式地为该端口分配一个临时随机端口终点。

因此,如果hostA启动连接,以下是您将看到的所有端点(您可以使用netstat查看这些连接)主机A:--听众:8000--连接到主机B:port8000,localport:xyz

旅馆B:--听众:8000--连接到主机A:端口:xyz,本地端口:8000

另一方面,如果hostB启动连接,以下是您会看到:主机A:

-- listener: 8000
-- connection to hostB:port:xyz', localport:8000

主机B:

 -- listener: 8000
    -- connection to hostA:port8000, localport:xyz'

在Internet中,BGP使用与连接2个TCP对等点类似的方法。