被动和主动插座

asl*_*nci 9 sockets port

引用此套接字教程:

插座有两种主要口味.活动套接字通过开放数据连接连接到远程活动套接字......无源套接字未连接,而是等待传入连接,一旦建立连接,将生成新的活动套接字...

每个端口可以有一个绑定到它的单个被动套接字,等待传入连接,以及多个活动套接字,每个套接字对应端口上的开放连接.好像工厂工人正在等待新消息到达(他代表被动套接字),当一条消息从新发送者到达时,他通过委派其他人(活动套接字)发起与他们的通信(连接)实际读取数据包并在必要时回复发件人.这允许工厂工人可以自由地接收新包....

然后教程解释说,在建立连接之后,活动套接字继续接收数据,直到没有剩余字节,然后关闭连接.

我不明白的是:假设有一个到端口的传入连接,并且发送者想要每20分钟发送一些小数据.如果活动套接字在没有剩余字节时关闭连接,则每次发送数据时发送方是否必须重新连接到端口?我们如何坚持一次建立的连接更长时间?你能告诉我我在这里失踪了吗?

我的第二个问题是,谁决定了同时工作的活动套接字的限制?

ktm*_*124 7

发送方应定期发送KEEPALIVE数据包以保持连接活动.KEEPALIVE的格式取决于协议.它可能小到TCP数据段中的单个NULL.

至于第二个问题......它取决于I/O. 如果它阻止I/O,那么您只需要在计算机上运行一定数量的线程,因此您将无法拥有多个客户端.如果它是非阻塞的,你可以拥有更多的客户端.编程语言应该支持阻塞和非阻塞I/O. (我知道Java的事实.)

它还取决于带宽,每个客户端的数据传输,内存,时钟速度等等.但是非阻塞与阻塞可以使您可以接受的客户端数量产生巨大差异.在没有服务器崩溃的情况下,您可能无法阻止超过5-10个客户端...但如果您没有阻止,则可以拥有数千个客户端.

  • 从客户的角度来看,对单个服务器的简单保持不是很多工作.当您连接到互联网时,您可能已经定期发送了六个Keepalive.从服务器的角度来看,将套接字列表中的套接字数量保持在最低限度可能是有利的,以提高I/O性能.如果在数据传输之间等待20分钟,我会每次都创建一个新连接.它对于客户端来说可以忽略不计,但对于服务器则不然. (2认同)

smi*_*-on 5

请不要混淆 TCP/IP 实现通过网络发送的实际数据包以及您的程序与实现 TCP/IP 的库之间的交互。

套接字只是通过 TCP/IP 实现(库或内核操作系统)呈现给您的程序的抽象。您可以将套接字视为与管道的连接(localIP:port-remoteIP:port)。您的程序打开套接字,通过套接字通信数据,如果不再需要帮助释放资源,可以关闭套接字。这是正常的流程。然而,TCP/IP 实现可能会出于其自身的正当原因关闭套接字。其中一些原因:网络访问电缆断开、网络路由错误、服务器宕机等。因此,即使您的程序没有关闭它,您的程序也可能会发现 tcp/ip 套接字已关闭。

现在你的第一个问题,如果我的程序发送小数据段,它们之间有很长的停顿,我该怎么办。答案是:取决于停顿多长时间以及另一边什么程序在听你。大多数 TCP/IP 实现都有连接超时的概念,以便为您提供真实不可靠网络上可靠连接的抽象。因此,如果您的程序暂停时间超过 tcp/ip 超时,您会发现您的套接字已被库关闭,您将需要重新打开套接字。这也可能导致您重新开始通信,这取决于在 tcp/ip 连接管道另一端侦听您的程序。

有一些方法可以增加 tcp/ip 超时并使其保持活动状态。这些可以作为网络配置的一部分、另一端的服务器软件配置来完成,或者通过在 tcp/ip 库调用中设置 KEEPALIVE 参数来明确要求保持套接字打开。它是否仍然开放取决于。tcp/ip 如何保持套接字打开的完整细节不应该让您感到困惑,因为它与您的代码无关。TCP/IP 有许多设置和不同的超时时间,为您的程序提供稳定可靠连接的错觉。只要您不滥用它,它的好处就全部隐藏在您的程序代码中。将您的暂停保持在几秒钟内 :) 一组超时设置可能适用于可靠本地网络中的小型应用程序,但不适用于高负载应用程序或跨大陆连接。

在这个特定问题“每 20 分钟发送一些小数据”中,我建议您为每次通信关闭和打开套接字连接。打开一个的时间不到一秒钟,应该不会影响您的交流。作为回报,您的通信协议的复杂性会降低。接收器总是在新的套接字连接上重新启动,当您不需要时,两个系统都可以在所有 20 分钟内享受 tcp/ip 通信中的免费资源。