【问题标题】:Send objects over socket repeatedly通过套接字重复发送对象
【发布时间】:2014-05-02 19:09:10
【问题描述】:

我正在尝试编写一个客户端-服务器应用程序,其中多个客户端可以在任何给定时间向服务器发送包含更新的对象。到目前为止,我设法将客户端连接到服务器并发送第一个对象,但我不能在以后发送对象(不建立新连接)。这是我的代码:

服务器:

ServerSocketChannel ssc = null;
try {
    ssc = ServerSocketChannel.open();
    ssc.socket().bind(new InetSocketAddress(port));
    ssc.configureBlocking(true);

    while (true) {
        SocketChannel sc = ssc.accept();
        ObjectInputStream ois = new ObjectInputStream(sc.socket().getInputStream());
        Object obj = ois.readObject();

        Client client = (Client)obj;                

        sc.close();
    }

} catch (IOException | ClassNotFoundException e) {

} finally {
    if (ssc != null) {
        try {
            ssc.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

客户:

SocketChannel sc;
ObjectOutputStream oos;

try {
    sc = SocketChannel.open();
    sc.configureBlocking(true);

    sc.connect(new InetSocketAddress(client.getPort()));

    try {
        /* While channel's socket is not connected */
        while (!sc.finishConnect()) {}
        /* Channel's socket is now connected */
        oos = new ObjectOutputStream(sc.socket().getOutputStream());
        sendClientObjectToServer();
    }
    catch (ConnectException e){}
} catch (IOException e) {}
finally {
    if (sc != null) {
        try {
            sc.close();
            oos.close();
        } catch (IOException e) {}
    }
}

public void sendClientObjectToServer() {
    try {
        oos.writeObject(client);
    }
    catch (IOException e){}
}

sendClientObjectToServer 方法第一次运行良好,但如果我稍后尝试调用它(按下 jbutton)会得到 ClosedChannelException。

编辑:找到solution。

【问题讨论】:

  • 每次需要与服务器通信时,都需要与服务器建立开放连接。一种选择是不关闭连接,除非应用程序关闭。
  • while (!sc.finishConnect()) {} 是主所憎恶的。如果要阻塞模式,为什么要使用非阻塞模式?

标签: java sockets objectoutputstream


【解决方案1】:

您必须保持 TCP 连接处于活动状态,以便以后能够发送更新,或者您可以使用 UDP 之类的东西(它也有自己的问题,例如丢包或双重接收),但不需要像 TCP 一样的“连接”。

这是你的问题:

    Client client = (Client)obj;                

    sc.close();

您将在客户端连接后立即关闭连接。

【讨论】:

  • 谢谢,这显然是一个错误。但是,它并不能解决我的问题。你能发现其他问题吗?
  • 好的,你的循环中的服务器正在接受一个连接,从输入流中读取一个对象,然后移动到下一个连接。如果您想从同一个客户端接收多条消息,您需要线程化您的服务器或只接受该线程上的一个客户端。记住 accept() 也是一个阻塞调用。
【解决方案2】:

无论如何,这永远不会奏效。您不能在非阻塞套接字通道上使用流。而且我永远不明白为什么人们以非阻塞模式连接,然后像上面那样编写'while(!sc.finishConnext()){}'循环。您只是将一个干净的阻塞机制换成了一个 CPU 吸烟自旋机制。这是毫无意义。执行连接并然后进入非阻塞模式,否则正确执行并选择 OP_CONNECT。但在这种情况下,您必须将其全部扔掉并使用 Socket。

【讨论】:

  • 连接Socket的代码是'new Socket(...)'。全部在 Javadoc 中,并且有一个非常好的自定义网络教程。
猜你喜欢
  • 2012-03-13
  • 2019-04-21
  • 2014-01-11
  • 2022-01-15
  • 2021-01-11
  • 2014-11-13
  • 2012-08-29
  • 1970-01-01
相关资源
最近更新 更多