反复通过套接字发送对象

时间:2014-05-02 19:09:11

标签: java sockets objectoutputstream

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

服务器:

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

2 个答案:

答案 0 :(得分:1)

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

这是你的问题:

    Client client = (Client)obj;                

    sc.close();

一旦连接,您就会关闭客户端上的连接。

答案 1 :(得分:0)

无论如何,这将永远不会奏效。您无法通过非阻塞套接字通道使用流。我永远不会理解为什么人们以非阻塞模式连接,然后写入' while(!sc.finishConnext()){}'如上所述的循环。您只是为CPU吸烟旋转机制交换一个漂亮的干净阻塞机制。这毫无意义。连接和然后进入非阻塞模式,否则正确执行并选择OP_CONNECT。但在这种情况下,你必须扔掉它并使用Socket。