简体   繁体   English

TCP客户端可以使用同一端口连接另一台服务器吗?

[英]Can a tcp client use the same port to a different Server?

I want to write a tcp server and client application, which has several different connections to each other where the client uses the same port number. 我想编写一个tcp服务器和客户端应用程序,它们在客户端使用相同端口号的情况下具有多个不同的连接。

So far I understand it, the server has a listener port and when the client calls it, then I get a new socket for this new connection on the server side, when I call 到目前为止,我理解它,服务器具有侦听器端口,当客户端调用它时,当我调用时,我会在服务器端为该新连接获得一个新的套接字

accept();

Right? 对? So on Server side I can identify my connection with this new socket and send data through it. 因此,在服务器端,我可以标识与此新套接字的连接并通过它发送数据。

Now my understanding problem with the client side. 现在我对客户端的理解问题。 There I get my socket when I call 打电话给我的地方

socket(AF_INET, SOCK_STREAM, 0) 

so I have only one socket. 所以我只有一个插座。 In the 在里面

connect() 

I can specify remote adress and so on. 我可以指定远程地址等等。 So when I understand it correctly I can use one socket to make several connects to different adresses/port pairs to create different connections. 因此,当我正确理解它时,我可以使用一个插座将多个连接连接到不同的地址/端口对,以创建不同的连接。 Right? 对?

But how can I now see in the Client from which logical connection I receive my data or how can I send it when 2 logical connections use the same local port at the client? 但是,现在如何在客户端中看到我从哪个逻辑连接接收数据,或者当两个逻辑连接在客户端使用相同的本地端口时如何发送数据呢? On serverside I have 2 sockets when I have 2 accept called but what about the client side? 在服务器端,当我有2个接受调用时,我有2个套接字,但是客户端呢? For send and receive I have only one socket handle? 对于发送和接收,我只有一个套接字句柄?

Or do I have to call socket() for each logical connection on the client? 还是我必须为客户端上的每个逻辑连接调用socket()?

I will not talk about a specific programming language rather I will give a general answer that is applicable for all: 我不会谈论特定的编程语言,而是会给出适用于所有人的一般性答案:

In networking what you care about is the socket (IP+Port) this should be unique whether it is server/client socket or UDP/TCP socket. 在网络中,您关心的是套接字(IP +端口),无论是服务器/客户端套接字还是UDP / TCP套接字,它都应该是唯一的。

For server sockets you must assign a port. 对于服务器套接字,您必须分配一个端口。 For client sockets usually you do not specifically assign a port but it will be assigned by the operating system automatically. 对于客户端套接字,通常不专门分配端口,但是操作系统会自动分配该端口。 However, you can still assign a port to a client socket manually (eg in case some port numbers are blocked by the firewall) 但是,您仍然可以手动将端口分配给客户端套接字(例如,如果某些端口号被防火墙阻止)

In the server process: you can get the server socket info and the connected client socket info 在服务器过程中:您可以获得服务器套接字信息和连接的客户端套接字信息

In the client process: you can get the client socket info and the server (you want to connect to) socket info (of course you should know the server socket info previously otherwise how will you connect to it). 在客户端过程中:您可以获得客户端套接字信息和服务器(要连接到)套接字信息(当然,您应该事先知道服务器套接字信息,否则将如何连接)。

You can send/receive from/to client sockets. 您可以从客户端套接字发送/从客户端套接字接收。 After the server gets the connected client socket it can send/receive through it. 服务器获得连接的客户端套接字后,它可以通过它发送/接收。 Same for the client side it can send/receive through its socket. 客户端也可以通过套接字发送/接收。

I can specify remote adress and so on. 我可以指定远程地址等等。 So when I understand it correctly I can use one socket to make several connects to different adresses/port pairs to create different connections. 因此,当我正确理解它时,我可以使用一个插座将多个连接连接到不同的地址/端口对,以创建不同的连接。 Right? 对?

No. A socket is the combination of IP address plus port number. 否。套接字是IP地址加端口号的组合。

Or do I have to call socket() for each logical connection on the client? 还是我必须为客户端上的每个逻辑连接调用socket()?

Yes. 是。

  • It seems to me your confusion arises because you think for example that a certain port is used for SMTP connections and a certain port is used for HTTP connections. 在我看来,您的困惑之所以出现,是因为您认为例如某个端口用于SMTP连接,而某个端口用于HTTP连接。

    Well, that port alone is NOT defining for you a socket to the server. 好吧,仅此端口并不能为您定义服务器的套接字。 The IP address of the server is changing. 服务器的IP地址正在更改。

    As an example, consider the following scenario: 例如,请考虑以下情形:

  1. You want to connection to Stackoverflow: 您要连接到Stackoverflow:

    Your PC – IP1 +port 50500 ——– Stackoverflow IP2 + port 80 (standard http port) 您的PC – IP1 +端口50500 ——– Stackoverflow IP2 +端口80 (标准的http端口)

    That is the combination IP1 + 50500 = the socket on the client computer and IP2 + port 80 = destination socket on the Stackoverflow server. IP1 + 50500 =客户端计算机上的套接字和IP2 +端口80 = Stackoverflow服务器上的目标套接字的组合。

  2. Now you want to connect to gnu.org: 现在,您要连接到gnu.org:

    your PC – IP1 +port 50501 ——–gnu.org IP3 +port 80 (standard http port) 您的PC – IP1 +端口50501 ——–gnu.org IP3 +端口80 (标准的http端口)

    The combination IP1 + 50501 = the socket on the client computer and IP3 + port 80 = destination socket on the gnu.org server. IP1 + 50501 =客户端计算机上的套接字,而IP3 +端口80 = gnu.org服务器上的目标套接字。

Better check out Beej's Network Programming to learn more. 最好查看Beej的网络编程以了解更多信息。 It is a must-read for anyone working with sockets. 对于使用套接字的任何人来说都是必读的。

So when I understand it correctly I can use one socket to make several connects to different adresses/port pairs to create different connections. 因此,当我正确理解它时,我可以使用一个插座将多个连接连接到不同的地址/端口对,以创建不同的连接。 Right? 对?

No. A TCP socket can only be used once. 否。TCP套接字只能使用一次。 When its connection has finished, or even if connect() just fails to make a connection, you must close the socket and create a new one if you want to make a new connection. 连接完成后,或者即使connect()未能建立连接,如果要建立新连接,也必须关闭套接字并创建一个新套接字。

But how can I now see in the Client from which logical connection I receive my data or how can I send it when 2 logical connections use the same local port at the client? 但是,现在如何在客户端中看到我从哪个逻辑连接接收数据,或者当两个逻辑连接在客户端使用相同的本地端口时如何发送数据呢?

Every TCP connection will have its own unique socket allocated for it. 每个TCP连接都会为其分配自己的唯一套接字。 It is your responsibility to keep track of them. 跟踪它们是您的责任。

On serverside I have 2 sockets when I have 2 accept called but what about the client side? 在服务器端,当我有2个接受调用时,我有2个套接字,但是客户端呢?

The exact same thing happens on the client side, too. 客户端也发生了完全相同的事情。 You need to create and connect a separate socket for every TCP connection you make. 您需要为建立的每个TCP连接创建并连接一个单独的套接字。 So, you will have a new pair of socket() / connect() calls for every connection. 因此,每个连接都会有一对新的socket() / connect()调用。

For send and receive I have only one socket handle? 对于发送和接收,我只有一个套接字句柄?

No, you will have a separate socket for each connection, just like on the server side. 不,您将为每个连接有一个单独的套接字,就像在服务器端一样。

Or do I have to call socket() for each logical connection on the client? 还是我必须为客户端上的每个逻辑连接调用socket()?

Yes, and connect() , too. 是的,也connect()

The "socket" abstraction is an unfortunate relic of past network stack design. “套接字”抽象是过去的网络堆栈设计的不幸产物。 It mixes two different sorts of objects. 它混合了两种不同类型的对象。

A listening socket on the server has a port, and potentially an IP address of the local interface. 服务器上的侦听套接字具有端口,并且可能具有本地接口的IP地址。 However, this can also be 0.0.0.0 when listening on all interfaces. 但是,在所有接口上侦听时也可以是0.0.0.0。

A connected socket is associated with a TCP connection, and therefore has 4 parameters: {local IP, local port, remote IP, remote port} . 连接的套接字与TCP连接相关联,因此具有4个参数: {local IP, local port, remote IP, remote port}

Now on the client side, you typically don't care about local IP or local port, so these are locally assigned on connect . 现在,在客户端,您通常不需要关心本地IP或本地端口,因此这些都是在connect上本地分配的。 And yes, these local parameters can in fact be reused for multiple connections. 是的,这些本地参数实际上可以重用于多个连接。 Only the 4-tuple of {local IP, local port, remote IP, remote port} needs to be unique. {local IP, local port, remote IP, remote port}的四元组仅是唯一的。 The OS will map that unique tuple to your SOCKET . 操作系统会将那个唯一的元组映射到您的SOCKET

But since you need a new 4-tuple for every connection, it also follows you need a new SOCKET on both sides, for every connection, on both client and server. 但是,由于每个连接都需要一个新的4元组,因此,客户端和服务器上的每个连接都需要一个新的SOCKET

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM