簡體   English   中英

Java:在套接字上重新連接有時會出錯

[英]Java: reconnection on a socket sometimes gives error

我正在制作原型客戶端和服務器,以便了解如何處理重新連接。 服務器應該創建一個 serversocket 並永遠監聽。 客戶端可以連接、發送其數據並關閉其套接字,但它不會向服務器發送“我完成並關閉”類型的消息。 由於這個原因,服務器在執行readByte()時會收到EOFException ,因為遠程客戶端已關閉。 EOFException的錯誤處理程序中,它將關閉套接字並打開一個新套接字。

這就是問題所在:客戶端在執行outputStream.write()調用時有時會收到SocketWriteError ,即使它成功打開了 socket/inputstream/outpustream。 這可能與我打開和關閉這些 sockets 的頻率有關。 一件有趣的事情是客戶端在退出之前會執行任意數量的寫入/關閉/重新連接。 有時它會在第一次重新連接時出錯,有時需要 50 次重新連接才能看到SocketWriteError

這是客戶端的錯誤:

java.net.SocketException: Connection reset by peer: socket write error
       at java.net.SocketOutputStream.socketWrite0(Native Method)
       at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
       at java.net.SocketOutputStream.write(SocketOutputStream.java:115)
       at bytebuffertest.Client.main(Client.java:37)

以下是一些代碼片段:

服務器:

public static void main(String[] args)
{
    Server x = new Server();
    x.initialize();
}

private void initialize()
{
    ServerSocket s;
    InputStream is;
    DataInputStream dis;
    while (true) //ADDED THIS!!!!!!!!!!!!!!!!!!!!!!
    {
        try
        {
            s = new ServerSocket(4448);
            s.setSoTimeout(0);
            s.setReuseAddress(true);
            is = s.accept().getInputStream();
            System.out.println("accepted client");
            dis = new DataInputStream(is);
            try
            {

                byte input = dis.readByte();
                System.out.println("read: " + input);
            } catch (Exception ex)
            {
                System.out.println("Exception");
                dis.close();
                is.close();
                s.close();
            }
        } catch (IOException ex)
        {
            System.out.println("ioexception");
        }
    }
}

客戶:

public static void main(String[] args)
{
    Socket s;
    OutputStream os;
    try
    {
        s = new Socket("localhost", 4448);
        s.setKeepAlive(true);
        s.setReuseAddress(true);
        os = s.getOutputStream();
        int counter = 0;
        while (true)
        {
            try
            {
                os.write((byte) counter++);
                os.flush();

                os.close();
                s.close();

                s = new Socket("localhost", 4448);
                s.setKeepAlive(true);
                s.setReuseAddress(true);
                os = s.getOutputStream();
            } catch (Exception e)
            {
                e.printStackTrace();
                System.err.println("ERROR: reconnecting...");
            }
        }
    } catch (Exception ex)
    {
        ex.printStackTrace();
        System.err.println("ERROR: could not connect");
    }
}

有誰知道如何正確重新連接?

不要在出錯時關閉 ServerSocket,只需.accept() 一個新連接。

我通常做的是每次 ServerSocket.accept() 返回一個 Socket 時,我會產生一個線程來處理來自該 Socket 的發送和接收。 這樣,一旦有人想連接到您,您就可以開始接受新連接。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM