Java - 客户端socket读取完成后保持连接

3
我对Java中的socket还不是很熟悉,但这是我的问题:
我编写了一个客户端线程类,将请求连接到由另一个应用程序创建的服务器(因此我没有为服务器类创建一个类)。基本上,该应用程序将传输一定数量的字节并关闭套接字的服务器端。我已经完全能够接收和处理这些字节。
我的问题是,客户端套接字是否可以被告知“等待”,直到来自相同地址/端口的另一个连接可用,并继续读取字节?(实质上,我运行应用程序,它读取字节并完成,然后我再次运行应用程序,客户端仍然能够读取)
以下是我的客户端线程代码:
public class ClientThread extends Thread{

    private Socket soc;
    private InputStream in;
    private String host;
    private int port;

public ClientThread(String host, int port)
{
    this.host = host;
    this.port = port;
    soc = null;
    in = null;
}

public boolean connectToServer()
{
    try {
        soc = new Socket(host, port);
        in = new BufferedInputStream(soc.getInputStream());
        System.err.println("Connection accepted: "+soc);
        return true;
    } catch (UnknownHostException e) {
        System.err.println("Unable to determine IP of host: "+host+".");
        return false;
    } catch (SocketException e) {
        System.err.println("Error creating or accessing the socket.");
        return false;
    } catch (IOException e) {
        System.err.println("Couldn't get I/O for the connection to: "+host+".");
        return false;
    }
}

public boolean disconnectFromServer()
{
    try {
        if(in != null)
            in.close();
        if(soc != null && soc.isConnected()) {
            soc.close();
            soc = null;
            System.err.println("Connection successfully closed!");
        }
        return true;
    } catch (Exception e) {
        System.err.println("Exception: "+e);
        return false;
    }
}

@Override
public void run() {
    try {
        int sz = 0;
        byte[] tmp = new byte[25];
        while(true)
        {
                if(sz == -1) {
                    sz = 0;
                }
                sz += in.read(tmp, sz, 25-sz);
                System.out.println(sz);
                if(sz == 25) {
                    tmp = new byte[25];
                    for(byte b: tmp)
                        System.out.print(b);
                    sz = 0;
                    Thread.sleep(500);
                }

        } 
    } catch (SocketException e) {
        System.err.println("Connection closed abruptly.");
    } catch (IOException e) {
        System.err.println("Couldn't get I/O for the connection to: "+host+".");
    } catch (InterruptedException e) {
        e.printStackTrace();
    }       
}
}
1个回答

1

accept()返回时,服务器将接收到一个套接字,只要该套接字没有被关闭,连接就保持打开状态。

因此,当您第一次运行应用程序,然后关闭服务器,再次运行它时,我认为连接将被断开,您必须重新初始化它。

isConnected()方法将给出错误结果,因为如果在客户端未显式关闭套接字,则始终会返回true

如果您想确保,可以先运行一次客户端-服务器连接,然后关闭服务器,重新启动它,然后尝试从/向服务器读取/写入。如果连接已断开,读取时将得到-1作为结果,写入时将得到IOException


好的,我相信当应用程序结束时连接会关闭。如果有新的服务器套接字可用,是否有一种高效的方法让客户端自动重新连接? - G Boggs
也许你可以编写一个Thread,使用我在答案中描述的方法定期检查连接(只需读取或写入,我猜读取可能是最简单的),当连接丢失时,调用一个打开连接的方法。 - JNevens
可能会起作用。但如果不麻烦的话,我还有另一个问题。假设在应用程序传输所有数据之前,我手动断开了客户端连接。然后我想重新连接客户端以完成读取其余数据。这是否可能?我打开了TCPview,并且它显示在我断开客户端连接后,应用程序的套接字仍在监听状态。 - G Boggs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接