【问题标题】:Reusing the inputstream of a socket重用套接字的输入流
【发布时间】:2011-06-14 14:24:26
【问题描述】:

我想知道如何保留套接字的输入流并重用它,直到应用程序关闭。 我现在要做的是在 main 方法中创建一个线程。该线程应该在应用程序运行的所有时间内保持运行。在这个线程中,我使用套接字输入流从服务器读取数据。但我只能读取一次服务器发送的内容。之后我认为线程已经死了,或者我无法从输入流中读取。我该如何做才能让输入流读取来自服务器的内容。 谢谢。

int length = readInt(input);


    byte[] msg = new byte[length];
    input.read(msg);
ByteArrayInputStream bs = new ByteArrayInputStream(msg);
            DataInputStream in = new DataInputStream(bs);
            int cmd = readInt(in);
switch(cmd) {
case 1: Msg msg = readMsg(cmd, msg);
}

我把所有东西都放在这里,但在我的代码中,事情以不同的方式发生。

readInt 方法:

public static int readInt(InputStream in) throws IOException {
    int byte1 = in.read();
    int byte2 = in.read();
    int byte3 = in.read();
    int byte4 = in.read();
    if (byte4 == -1) {
        throw new EOFException();
    }
    return (byte4 << 24)
            + ((byte3 << 24) >>> 8)
            + ((byte2 << 24) >>> 16)
            + ((byte1 << 24) >>> 24);
}

用于小端转换。

【问题讨论】:

  • 给我们看一些代码。听起来好像没有什么可以从套接字读取,所以read() 正在阻塞(等待有数据读取)。
  • 我建议附上一些打印语句让你知道发生了什么,或者在一个好的调试器下运行它,这样你就可以看到什么正在运行以及它何时停止运行。如果没有代码或对问题所在的实际了解,我们不太可能为您提供太多帮助。
  • 另外:你使用什么协议?您确定既不客户端也不服务器正在关闭套接字(或其流)?

标签: java sockets tcp


【解决方案1】:

你的套接字很可能被阻塞了。如果您遇到这样的问题,一种好方法是为您的软件设计一种轮询方法,而不是中断驱动。话又说回来,软件设计模式将围绕您想要实现的目标来完成。

希望对您有所帮助!干杯!

【讨论】:

  • 我正在 netbeans 分析器中运行应用程序,我看到我的线程运行代码以读取服务器正在发送的内容已完成...线程完成后我从服务器。
  • 为什么完成了?出于某种原因,它是否超出了您的 read() 循环?
  • 但我不知道它为什么会结束,它似乎并没有排除任何东西。那是我的运行方法: public void run() { try { handleReadServer(in); } catch (Exception ex) { Logger.getLogger(Clazz.class.getName()).log(Level.SEVERE, null, ex); } },如果抛出一些异常,我会看到它,但我什么也看不到。
  • handlReadServer() 例程中有什么?也许您可以更新您的帖子并将代码的那部分粘贴到那里供我们结帐?干杯!
  • 您的代码在上次读取时被阻塞。参考:download.oracle.com/javase/6/docs/api/java/io/…。如果您愿意,您可以考虑将自己的字符分隔符作为流的结尾发送,这将根据规范返回 -1。
【解决方案2】:

您需要在这样的循环中调用 input.read():

try {
    while(running) {
        int length = readInt(input);
        byte[] msg = new byte[length];
        input.read(msg);
        ByteArrayInputStream bs = new ByteArrayInputStream(msg);
            DataInputStream in = new DataInputStream(bs);
            int cmd = readInt(in);
        switch(cmd) {
            case 1: Msg msg = readMsg(cmd, msg);
        }

     }
} catch (IOException e) { 
    //Handle error
}

当你完成你的线程需要做的事情时,将 running 设置为 false。请记住 input.read() 将阻塞,直到套接字收到某些内容。我希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2012-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多