首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >客户端在服务器关闭连接(Java)之前不会收到响应消息

客户端在服务器关闭连接(Java)之前不会收到响应消息
EN

Stack Overflow用户
提问于 2016-08-29 16:37:52
回答 3查看 3K关注 0票数 1

我的同事和我正在开发一个与web服务通信的客户端应用程序,以便处理一些事务数据。以下是我们沟通的步骤:

  1. 客户端应用程序启动连接并发送请求消息(timestamp = T1)
  2. Web接受连接并处理请求(timestamp ≈ T1)
  3. Web返回响应消息(timestamp = T1 + few_seconds)
  4. Web服务关闭连接(timestamp = T1 + 3_minutes)
  5. 客户端应用程序获取响应消息并继续进行数据解析(timestamp = T1 + 3_minutes)

我们的问题在于时间戳引用: web服务处理请求并几乎立即检索响应,但客户端应用程序在服务器关闭连接之前不会收到响应消息。以下是日志文件:

客户端应用程序日志片段:

代码语言:javascript
运行
复制
10:46:25,031 INFO  MessageHandler.java:115 Message sent.
10:49:25,071 INFO  MessageHandler.java:125 Message received.
10:49:25,103 DEBUG  MessageParser.java:67 Message parsed.

服务器应用程序日志:

代码语言:javascript
运行
复制
10:46:25:153 <INFO>   Client connection accepted.
...
10:46:26:602 <INFO>   Response message sent.
...
10:49:25:069 <INFO>   Closing connection...

如您所见,只有当服务器关闭连接时,客户端才会获得响应。

下面是进行通信的方法的客户端应用程序代码:

代码语言:javascript
运行
复制
public static String sendMsg(byte[] msg, String serverIp, int port) {
    try {
            InetAddress address = InetAddress.getByName(serverIp);
            Socket socket = new Socket(address, port);
            OutputStream os = socket.getOutputStream();

            logger.info("Message sent.");

            os.write(msg, 0, msg.length);
            os.flush();

            InputStream is = socket.getInputStream();
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);
            String msgReceived = br.readLine();

            logger.info("Message received.");
            os.close();
            return msgReceived;
        } ...(catch blocks) ... 
}

假设我们无法更改web服务实现,在服务启动响应时(然后由客户端关闭连接),是否有一种方法可以立即在客户端获取响应消息?提前谢谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-08-29 18:31:02

很可能,客户端没有正确地实现消息协议。例如,客户机调用readLine。消息协议是否指定消息为一行?如果没有,readLine将继续等待,直到连接关闭,仍然试图获得永远不会发送的线路。

除非客户端理解如何分隔消息,否则将无法找到消息的结尾。在您的协议中如何分隔消息?检测消息结束的客户端代码在哪里?如果不是你写的,就不会发生。

票数 3
EN

Stack Overflow用户

发布于 2016-08-29 16:41:31

听起来你不太可能从客户端做些什么。可能发生的情况是,web服务器正在缓冲来自webservice的响应(因此它可以设置内容长度、标题等)。因此,在webservice关闭连接之前,不会发送任何数据。通过使用br.read()方法读取数据的单个字符,而不是像现在这样一次读取整行数据,您可以间接地检验这一假设。

票数 1
EN

Stack Overflow用户

发布于 2016-08-29 18:26:10

正如@Yeroc所建议的那样,似乎web服务器正在缓冲其响应,并且在出现超时之前不会刷新缓冲区。(在服务器端,我认为这是一个糟糕的设计选择,但如果您无法控制服务器,那么您可能会被困在服务器上。)

我会尝试在客户端做一个shutdown(SHUT_WR)。这应该会在服务器中产生一个“文件结束”指示,这可能会导致它刷新其缓冲区并关闭连接。因为这正是你想要的,这可能会让你反应得更快。带有shutdownSHUT_WR只在一个方向关闭连接--客户机到服务器方向--所以您仍然能够接收响应。

(服务器可能不需要刷新就可以选择close,但刷新缓冲区很可能是服务器端高级close调用的副作用,因此绝对值得一试。)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39211079

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档