Java ServerSocket 和使用 ObjectIOStreams 的套接字会丢失数据包吗?

Posted

技术标签:

【中文标题】Java ServerSocket 和使用 ObjectIOStreams 的套接字会丢失数据包吗?【英文标题】:Can Java ServerSocket and Sockets using ObjectIOStreams lose packets? 【发布时间】:2011-02-12 17:43:18 【问题描述】:

我在我的服务器上使用 ServerSocket 和使用 Objectiostreams 通过网络连接发送可序列化对象的套接字。我正在开发一个本质上更加金融版的垄断,因此需要发送和确认发送/接收的数据包。我是否需要实现自己的丢包观察器,还是已经使用 (Server)Sockets 处理了?

我主要是询问在网络中断或诸如此类的情况下丢失数据包,而不是完全连接错误。例如。兄弟姐妹在我的路由器和计算机的 wi-fi 适配器之间移动一个引线板。

http://code.google.com/p/inequity/source/browse/#svn/trunk/src/network 代码可以在network->ClientController和network->Server下找到

【问题讨论】:

【参考方案1】:

理论上;是的。没有办法 100% 理论上保证在硬件层发送的内容在接收端以相同的方式接收。

然而,实际上,如果您使用 TCP(传输控制协议),这些东西已经被处理好了;你不会丢失任何数据包。 (另一方面,如果您使用的是 UDP(用户数据报协议),那就另当别论了,您很可能会丢失数据包,或者无序地接收数据包)。

只是简单地查看了您的代码,您似乎正在使用多个线程。如果是这样,您必须非常小心同步。很有可能看起来一个数据包已被丢弃,但由于程序中的竞争条件,它根本没有被处理。 (请记住,例如 gui,在它自己的线程中运行。)

我认为解决同步问题的最佳方法是将网络循环置于一个非常小的读取/放置同步队列循环中,并在您确定没有时从队列中提取接收到的数据包其他线程将介入。

【讨论】:

'理论上;是的。'理论上没有。他正在使用 ServerSocket,这意味着 TCP,以及 ObjectInputStream 和 ObjectOutputStream,同上。他不可能像描述的那样使用UDP。他不可能遇到丢包。他的代码中有一个错误。 我明白了。 ServerSocket 意味着 TCP。我没有想到。你说得对。谢谢。但是,我不相信有理论上的保证接收到的数据与发送的数据相同。硬件可能会在传输的某处误解位。大多数位错误会被奇偶校验所覆盖,但有些错误当然会被忽视。我知道我过于正式(由于三年的正式方法研究生学习,这是一个坏习惯)。 当然有保证。请参阅 RFC。它由校验和强制执行。 我明白你的意思,我意识到我过于正式,但考虑一下如果硬件层没有提供任何保证并且可以任意翻转位,理论上会发生什么:假设你有一个数据数组 D0,当在网络上发送时,它看起来像一个比特流(包括校验和、奇偶校验等等),称之为 BITS0。我尝试发送一些其他数据 D1(转换为 BITS1)。硬件层意外翻转了大部分位,因此流被接收为 BITS0。接收者将无法说“嘿,已损坏,请重新发送”。 那么你就走上了正轨。无需担心丢包。 (因为你使用的是 tcp,而不是 udp)

以上是关于Java ServerSocket 和使用 ObjectIOStreams 的套接字会丢失数据包吗?的主要内容,如果未能解决你的问题,请参考以下文章

Java]Socket和ServerSocket服务器端接受数据

系统运维系列 之Socket和ServerSocket的简单介绍(java应用)

java中用serverSocket类如何向指定IP的客户端发送数据

ServerSocket和Socket

java通过ServerSocket与Socket实现通信

java通过ServerSocket与Socket实现通信