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

时间:2019-02-19 08:05:10

标签: c++ sockets tcp

我想编写一个tcp服务器和客户端应用程序,它们在客户端使用相同端口号的情况下具有多个不同的连接。

到目前为止,我理解它,服务器具有一个侦听器端口,当客户端调用它时,当我调用

时,我会在服务器端获得一个用于此新连接的新套接字。
accept();

对吗?因此,在服务器端,我可以识别与此新套接字的连接并通过它发送数据。

现在我在客户端的理解问题。呼叫

socket(AF_INET, SOCK_STREAM, 0) 

所以我只有一个插座。在

connect() 

我可以指定远程地址等等。因此,当我正确理解它时,我可以使用一个插座将多个连接连接到不同的地址/端口对,以创建不同的连接。对吧?

但是,现在如何在客户端中看到我从哪个逻辑连接接收数据,或者当两个逻辑连接在客户端使用相同的本地端口时如何发送数据呢?在服务器端,当我有2个接受调用时,我有2个套接字,但是客户端呢?对于发送和接收,我只有一个套接字句柄?

还是我必须为客户端上的每个逻辑连接调用socket()?

4 个答案:

答案 0 :(得分:2)

我不会谈论特定的编程语言,而是会给出适用于所有人的一般性答案:

在网络中,您关心的是套接字(IP +端口),无论是服务器/客户端套接字还是UDP / TCP套接字,它都应该是唯一的。

对于服务器套接字,您必须分配一个端口。对于客户端套接字,通常不专门分配端口,但是操作系统会自动分配该端口。但是,您仍然可以手动将端口分配给客户端套接字(例如,在某些端口号被防火墙阻止的情况下)

在服务器进程中: 您可以获得服务器套接字信息和连接的客户端套接字信息

在客户端流程中: 您可以获得客户端套接字信息和服务器(要连接)套接字信息(当然,您应该事先知道服务器套接字信息,否则将如何连接)。

您可以从客户端套接字发送/从客户端套接字接收。服务器获得连接的客户端套接字后,它可以通过它发送/接收。客户端也可以通过套接字发送/接收。

答案 1 :(得分:1)

  

我可以指定远程地址等等。因此,当我正确理解它时,我可以使用一个插座将多个连接连接到不同的地址/端口对,以创建不同的连接。对吧?

不。套接字是IP地址加端口号的组合。

  

还是我必须为客户端上的每个逻辑连接调用socket()?

是的

  • 在我看来,您的困惑之所以出现,是因为您认为例如某个端口用于SMTP连接,而某个端口用于HTTP连接。

    嗯,仅此端口并不能为您定义服务器的套接字。服务器的IP地址正在更改。

    作为示例,请考虑以下情形:

  
      
  1. 您要连接到Stackoverflow:

         

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

         

    这是组合 IP1 + 50500 =客户端计算机上的插槽和 IP2 +端口 80 = Stackoverflow服务器上的目标套接字。

  2.   
  3. 现在您要连接到gnu.org:

         

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

         

    组合 IP1 + 50501 =客户端计算机上的插槽, IP3 +端口 80 =目标gnu.org服务器上的套接字。

  4.   

最好查看Beej's Network Programming了解更多信息。这是任何使用套接字的人必读的内容。

答案 2 :(得分:1)

  

因此,当我正确理解它时,可以使用一个套接字将多个连接连接到不同的地址/端口对,以创建不同的连接。对吧?

不。一个TCP套接字只能使用一次。连接完成后,或者即使connect()未能建立连接,如果要建立新的连接,也必须关闭套接字并创建一个新的套接字。

  

但是现在如何在客户端中看到我从哪个逻辑连接接收数据,或者当两个逻辑连接在客户端使用相同的本地端口时如何发送数据?

每个TCP连接都会为其分配一个唯一的套接字。跟踪它们是您的责任。

  

在服务器端,当我有2个接受调用时,我有2个套接字,但是客户端呢?

完全相同的事情也在客户端发生。您需要为建立的每个TCP连接创建并连接一个单独的套接字。因此,每个连接都会有一对新的socket() / connect()通话。

  

对于发送和接收,我只有一个套接字句柄?

否,就像服务器端一样,每个连接都有一个单独的套接字。

  

还是我必须为客户端上的每个逻辑连接调用socket()?

是,还有connect()

答案 3 :(得分:-2)

“套接字”抽象是过去的网络堆栈设计的不幸产物。它混合了两种不同类型的对象。

服务器上的监听套接字具有端口,并且可能具有本地接口的IP地址。但是,在所有接口上侦听时也可以是0.0.0.0。

连接的套接字与TCP连接关联,因此具有4个参数:{local IP, local port, remote IP, remote port}

现在在客户端,您通常不必关心本地IP或本地端口,因此这些都是在connect上本地分配的。是的,这些本地参数实际上可以重用于多个连接。 {local IP, local port, remote IP, remote port}的仅四元组需要唯一。操作系统会将唯一元组映射到您的SOCKET

但是由于每个连接都需要一个新的4元组,因此随之而来的是,客户端和服务器上的每个连接都需要一个新的SOCKET