无源和有源套接字
引用这个套接字教程:
套接字有两种主要类型。 活动套接字连接到 通过开放数据的远程活动套接字 连接...被动套接字是 未连接,而是等待 传入连接,这将 一旦产生一个新的活动套接字 连接已建立 ...
每个端口可以有一个被动 套接字绑定到它,等待 传入连接,以及 多个活动套接字,每个 对应于一个开放的 端口上的连接。就好像 工厂工人正在等待新的 消息到达(他代表 无源套接字),并且当一个 消息来自新发件人,他 发起通信(a 连接)与他们通过 委托他人(主动 socket) 来实际读取数据包 并回复发件人,如果 必要的。这允许工厂 工人可以自由地接收新的 数据包。 ...
然后教程解释说,建立连接后,活动套接字继续接收数据,直到没有剩余字节,然后关闭连接。
我不明白的是:假设有一个到端口的传入连接,并且发送者希望每 20 分钟发送一些小数据。如果活动套接字在没有剩余字节时关闭连接,那么发送方每次想要发送数据时都必须重新连接到该端口吗?我们如何才能将曾经建立的连接保持更长时间?你能告诉我我在这里缺少什么吗?
我的第二个问题是,谁确定并发工作的活动套接字的限制?
Quoting from this socket tutorial:
Sockets come in two primary flavors.
An active socket is connected to a
remote active socket via an open data
connection... A passive socket is
not connected, but rather awaits an
incoming connection, which will
spawn a new active socket once a
connection is established
...Each port can have a single passive
socket binded to it, awaiting
incoming connections, and
multiple active sockets, each
corresponding to an open
connection on the port. It's as if
the factory worker is waiting for new
messages to arrive (he represents
the passive socket), and when one
message arrives from a new sender, he
initiates a correspondence (a
connection) with them by
delegating someone else (an active
socket) to actually read the packet
and respond back to the sender if
necessary. This permits the factory
worker to be free to receive new
packets.
...
Then the tutorial explains that, after a connection is established, the active socket continues receiving data until there are no remaining bytes, and then closes the connection.
What I didn't understand is this: Suppose there's an incoming connection to the port, and the sender wants to send some little data every 20 minutes. If the active socket closes the connection when there are no remaining bytes, does the sender have to reconnect to the port every time it wants to send data? How do we persist a once established connection for a longer time? Can you tell me what I'm missing here?
My second question is, who determines the limit of the concurrently working active sockets?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
发送方应定期发送 KEEPALIVE 数据包以保持连接处于活动状态。 KEEPALIVE 的格式取决于协议。它可以小到 TCP 数据段中的单个 NULL。
至于第二个问题...这取决于I/O。如果它阻塞 I/O,那么您只希望计算机上运行一定数量的线程,因此您将无法拥有许多客户端。如果它是非阻塞的,您可以拥有更多的客户端。编程语言应该支持阻塞和非阻塞 I/O。 (我知道 Java 确实如此。)
它还取决于带宽、每个客户端的数据传输、内存、时钟速度等因素。但是非阻塞与阻塞可以在客户端数量上产生巨大差异你可以接受。您可能无法让超过 5-10 个客户端阻塞而不导致服务器崩溃……但如果您不阻塞,则可以有数千个客户端。
The sender should send a KEEPALIVE packet at regular intervals to keep the connection alive. The format of the KEEPALIVE depends on the protocol. It could be as small as a single NULL in the TCP data segment.
As to the second question... it depends on the I/O. If it is blocking I/O then you only want a certain number of threads running on your computer, so you won't be able to have many clients. If it's non-blocking, you can have a lot more clients. Programming languages should have support for both blocking and non-blocking I/O. (I know for a fact that Java does.)
It also depends on things like bandwidth, the data transfer for each client, memory, clock speed, etc. But non-blocking vs. blocking can make a huge difference in the number of clients you can accept. You probably can't have more than 5-10 clients blocking without your server crashing... but you can have thousands if you're not blocking.
请不要混淆 TCP/IP 实现通过网络发送的实际数据包以及您的程序和实现 TCP/IP 的库之间的交互。
套接字只是通过 TCP/IP 实现(库或内核操作系统)呈现给您的程序的抽象。您可以将套接字想象为与管道的连接(本地IP:端口-远程IP:端口)。您的程序打开套接字,通过套接字通信数据,如果不再需要,可以关闭套接字以帮助释放资源。这是正常的流量。然而,TCP/IP 实现可能会由于其自身的正当原因而关闭套接字。其中一些原因:网络访问电缆断开、网络路由错误、服务器宕机等。因此,您的程序可能会发现 tcp/ip 套接字已关闭,即使它没有关闭它。
现在你的第一个问题是,如果我的程序发送的小数据段之间有很长的停顿,我该怎么办。答案是:取决于停顿的时间以及另一边听你的是什么程序。大多数 TCP/IP 实现都有连接超时的概念,为您提供真实不可靠网络上可靠连接的抽象。因此,如果您的程序暂停时间超过 tcp/ip 超时,您将发现您的套接字已被库关闭,并且您将需要重新打开套接字。这也可能导致您重新启动通信,具体取决于在 tcp/ip 连接管道另一端侦听您的程序。
有多种方法可以增加 tcp/ip 超时并保持其活动状态。这些可以作为网络配置、另一端服务器软件配置的一部分来完成,或者通过您通过在 tcp/ip 库调用中设置 KEEPALIVE 参数来明确要求保持套接字打开来完成。是否仍然开放取决于。 tcp/ip 如何保持套接字打开的完整细节不应让您感到困惑,因为它与您的代码无关。 TCP/IP 有许多设置和不同的超时,为您的程序提供稳定可靠连接的错觉。好的部分是,只要您不滥用它,它就会对您的程序代码隐藏起来。将暂停时间控制在几秒钟之内:) 一组超时设置可能适用于可靠本地网络中的小型应用程序,但不适用于高负载应用程序或跨大陆连接。每种具体情况都有其自己的解决方案,而且往往不止一种。
在这个具体问题“每 20 分钟发送一些小数据”中,我建议您关闭并打开每次通信的套接字连接。打开一个的时间不到一秒,不会影响您的沟通。作为回报,您的通信协议的复杂性会降低。接收器始终在新的套接字连接上重新启动,并且当您不需要时,两个系统都可以在 20 分钟内享受 tcp/ip 通信的免费资源。
Please do not confuse actual packets sent by TCP/IP implementation over network and interaction between your program and a library that implements TCP/IP.
The socket is just an abstraction that is presented to your program by TCP/IP implementation (library or kernel OS). You may visualize socket as connection to the pipe (localIP:port-remoteIP:port). Your program opens socket, communicates data over socket and may close the socket if no longer needed to help free resources. This is normal flow. However TCP/IP implementation may close socket for its own valid reasons. Some of those reasons: network access cable disconnection, network routing errors, server went down, etc. Thus your program may find tcp/ip socket closed even if it did not close it.
Now your first question, what do I do if my program sends small data segments with long pause between them. The answer is: depends on how long is the pause and what program listens you on other side. Most TCP/IP implementations have a notion of connection time out to provide you abstractions of reliable connection over real unreliable networks. Thus if your program will pause longer than tcp/ip timeout you will find your socket been closed by the library and you will need to re-open socket. That may also cause your to restart communication over again, depends on a program that listens for you on other side of the tcp/ip connection pipe.
There are ways of increasing tcp/ip timeout and keeping it alive. Those may be done as part of network configuration, the server software configuration on other end or by you explicitly asking to keep socket open by setting KEEPALIVE parameters in your tcp/ip library call. Would it be still open or not depends. The full details of how tcp/ip would keep socket open should not confuse you as it has nothing to do with your code. TCP/IP has many settings and different timeouts to provide your program with illusion of stable reliable connection. The good part it is all hidden from your program code as long as you not abuse it. Keep your pause under few seconds :) One set of timeout settings may work well for small applications in reliable local network and will not work for high load applications or over cross-continent connectivity. Each specific situation has its own solution, often more than just one.
In this specific question "to send some little data every 20 minutes" I would advise you to close and open socket connection for each communication. The time to open one is less than a second and should not impact your communication. In return you get less complexity in your communication protocol. Receiver is always starts fresh on new socket connection and both systems may enjoy free resources in tcp/ip communication over all 20 minutes when you don't need it.
第一个问题:
是的,一旦套接字关闭,您必须执行打开操作才能重新启动通信。
第二个问题:
你做。如果您愿意,您可以创建到服务器的 64k 连接并遭受端口耗尽(我不建议这样做)。正如 ktm5124 所说,这完全取决于您的应用程序。有几种不同的方法可以使服务器可扩展,包括使用异步 I/O 和/或线程池来处理客户端请求。
First question:
Yes, once a socket is closed you must do an Open to re-initiate communication.
Second Question:
You do. If you want you can create 64k connections to your server and suffer port exhaustion (I don't recommend that). Like ktm5124 stated, it all depends on your application. There are several different ways to make your server scalable including using async I/O and or a thread pool to handle client requests.