【问题标题】:Java Socket Bug: Reading Strings from Socket's InputStreamJava Socket 错误:从 Socket 的 InputStream 中读取字符串
【发布时间】:2011-06-10 18:10:59
【问题描述】:

我正在使用 Socket 与 ServerSocket 进行通信。字符串正在从服务器发送到我的套接字。每个不同的行都是一条消息,在解析时包含信息。要阅读这些文本行,需要使用扫描仪。

问题在于数据是“突飞猛进”的。虽然Server在连续均匀的发送数据,但是client端的Scanner读取的数据似乎暂停了,一下子读入了一堆消息(30-40),然后又暂停了。它无限期地重复这个循环。

如果我提高发送数据的速率,暂停的持续时间会减少;如果我减慢数据速度(每秒 1 条消息),错误仍然存​​在并且暂停变得很长。就好像 Socket 在向 Scanner 发送任何数据之前等待其缓冲区溢出一样;然后刷新所有内容并再次等待溢出。但是,如果我减小 Socket 缓冲区的大小,则根本没有任何变化。

应该注意的是,我以前在这种方法中使用过 Scanner 和 Socket - 从服务器端 - 一切都按预期工作。此外,我 a) 使用 Java Tutorials 之类的 BufferedReader 进行了尝试(错误中没有变化),b) 将服务器传输列表打印到文件中,并以相同的方式从文件中读取,程序按预期工作(消息接收的恒定速率等)所以问题似乎出在 Socket 本身。

那么:我该如何解决这个问题?我没有想法 atm,我真的不知道发生了什么。

代码(根据要求):

// In try block
// Makes the connection
Socket connection = new Socket(TARGET_MACHINE, PORT_NUMBER);
Scanner reader = new Scanner(connection.getInputStream());

// In new Thread
// In run()
while(!finished) // Boolean exit strategy
{
    if(reader.hasNextLine())
        Sring message = reader.nextLine();
}

这就是我连接和检索字符串的方式。

另外,我收到的字符串通常大约 20-40 个字符长。

【问题讨论】:

  • 贴一些代码,看看发生了什么。
  • 这不是错误,而是一项功能。可能您在发送方有一些缓存,您必须明确刷新。
  • 您的 TCP 堆栈可能会将多条消息组合成单个数据包以优化网络流量。如果消息足够短,则可以将 30-40 条消息放入一个数据包中。如果没有代码和更多关于“非常长”的停顿时间的详细信息,将很难诊断。

标签: java debugging sockets client-server


【解决方案1】:

每次从服务器端写入流时,是否刷新流?它可能正在缓冲输出并且在达到某个阈值之前不将其写入流。

【讨论】:

  • 假设您使用的是 OutputStream,它只是 .flush()。输出流 os = socket.getOutputStream(); os.flush();流编写器也有类似的方法。 BufferedWriter bw = ...; bw.flush();
  • 甜蜜,解决了它。谢谢。 :D
【解决方案2】:

你可能会使用 readLine 来读取数据吗?

以下是 javadoc 的摘录,您可能会感兴趣:

由于此方法继续搜索输入以查找行分隔符,因此如果不存在行分隔符,它可能会缓冲所有搜索要跳过的行的输入。

你能附上客户端和服务器代码看看有什么问题吗?您最好使用非常简单的逐字节读取器来检查来自服务器的流是否在传输中暂停,也许问题在于您将数据写入服务器套接字的方式......没有代码很难猜测:)

【讨论】:

  • 是的,我注意到了那行,但是我之前一直在使用 Scanner 来解析 Socket 消息,我没有发现任何问题。主要问题似乎在于 Socket 连接;我想看看我能不能先解决这个问题。
猜你喜欢
  • 2017-07-15
  • 2015-07-11
  • 2015-05-23
  • 2011-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-23
相关资源
最近更新 更多