适用于高负载网络应用的最高效的 winsock 设计
我知道这是一个普遍问题,但我需要您对 TCP 服务器/客户端应用程序的建议。
服务器一次只能处理一个连接。 服务器正在向连接的客户端发送实时图像(一帧约为 50K,每秒 20 帧)。
实际上,在服务器和客户端应用程序启动时就建立了连接,理论上该连接应该永远保持活动状态。
我的观点是,由于服务器正在发送实时图像,因此延迟必须最小,因此编写这样一个(简单)tcp 服务器和客户端的最佳实践是什么,以及如何序列化/反序列化图像以实现“最小延迟”目标实现了吗?
提前致谢,
问候
I know it is a general question but I need your recommodations about a TCP server/client application.
The server is only supposed to handle one connection at a time.
Server is sending live images (one frame is approx. 50K and 20 frames per second) to connected client.
Actually at the startup of the server and client applications connection is established and this connection is supposed to be keep alive forever,in theory.
My point is that since server is sending live images, delay must be minimum, so what is best practice for writing such a (simple) tcp server and client, and how to serialize/deserialize images so that "minumum delay" aim is achieved?
Thanks in advance,
Regards
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不是超级权威,但是...
让我们做一些数学计算。 每张图像 50K(这是字节,对吧?),每秒 20 帧,大约每秒 1 兆字节。 在通信方面,即每秒 10 兆比特。 这是相当合理的一点,但非常可行。 确保您自始至终都拥有 100 兆比特的设备。
最快的 API 是无聊的旧阻塞“send”和“recv”调用(*1)。 还有其他调用执行 Windows IO 类型完成端口等操作; 不要将它们用于此应用程序(因为 (a) 它们太过分了,并且 (b) 它们使应用程序更具可扩展性)
考虑关闭 Nagle(NODELAY 选项)。
(*1) 可能。 关于实际最快的 Winsock 调用的实际文献严重缺乏。
I'm not super-authoritative, but...
Let's do some math. 50K per image (that's bytes, right?) at 20 frames per second is about 1 megabyte per second. In communications terms, that's 10 megabits per second. That's a fair-ish bit, but very do-able. Be sure you've got 100 megabit equipment throughout.
The fastest APIs for this are the boring old blocking "send" and "recv" calls (*1). There are other calls which do the Windows IO type completion ports and whatnot; don't use them for this application (because (a) they are overkill and (b) they make an app be more scalable)
Consider turning off the Nagle (the NODELAY option).
(*1) probably. The actual literature on the actual fastest Winsock calls is severely lacking.
一种方法是使用 UDP 而不是 TCP 发送数据。
如果这样做,一些 UDP 数据包可能会丢失(被网络丢弃),因此您的代码将需要一种方法(例如数据包标头中的序列号)来检测丢失的数据包。
如果 TCP 数据包丢失,则 TCP 将重新传输它,这会导致延迟。 对于您的应用程序来说,当数据包丢失时,您可能只想删除丢失的数据包,而不是重新传输它,不显示此视频帧(或仅显示部分帧),然后继续显示下一个视频帧框架。
这取决于应用程序:
您是否正在流式传输录制/预先录制/非实时视频,您希望在其中接收/显示每一帧,即使其中一些会导致延迟? p>
您是否正在流式传输实时视频,希望近乎实时地显示当前帧(即使之前的一些帧丢失,您也不希望在重新传输它们时出现延迟)?
就winsock架构而言,
TransmitFile
或TransmitPackets
API非常高效:它们在内核中执行,而不是导致用户模式代码和O/ S 内核模式代码随着每个缓冲区被传输。您可能需要一些延迟,以避免抖动:最好有一个小的(例如 150 毫秒)固定延迟,而不是 2 到 120 毫秒的延迟。 请参阅 http://www.google.ca/search?hl=en& ;q=抖动+网络
One way is to send the data using UDP instead of TCP.
If you do, it's possible that some of the UDP packets will be lost (dropped by the network), so your code will need a method (e.g. sequence number in the packet headers) to detect lost packets.
If a TCP packet is lost, then TCP will retransmit it, which results in a delay. It's possible that for your application, when a packet is lost you might just want to do without that lost packet, not retransmit it, don't display this video frame (or display only the partial frame), and go on to display the next frame.
It depends on the application:
Are you streaming canned/prerecorded/non-real-time video, where you want to receive/display every frame even if some of them cause a delay?
Are you streaming live video, where you want to display the current frame in near-real-time (and even if some previous frames were lost, you don't want to delay while they're retransmitted)?
In terms of winsock architecture, the
TransmitFile
orTransmitPackets
APIs are quite efficient: they're executing in the kernel, instead of causing round trips between your user mode code and O/S kernel mode code as each buffer is transmitted.You may want some delay, to avoid jitter: better to have a small (e.g. 150 msec) fixed delay, than a delay which varies from 2 to 120 msec. See http://www.google.ca/search?hl=en&q=jitter+network