Java: как определить на сервере, был ли закрыт сокет клиента? - PullRequest
1 голос
/ 25 апреля 2011

Среда: Java 6, Windows XP

Я пытаюсь написать клиент-серверное приложение TCP-сокета. Необходимо определить на сервере, когда клиент закрыл сокет. Вся информация в Интернете говорит о том, что сервер сгенерирует сокет исключения, когда его не удастся записать.

Однако, когда я запускаю код (см. Ниже), я вижу, что сервер получает исключение только , когда клиент ничего не читает из потока. Когда клиент читает из входного потока, на сервере не возникает никаких исключений.

Может кто-нибудь сказать мне правильный способ обнаружения закрытия сокета на стороне клиента (а также объяснить поведение, показанное кодом ниже)?

Код:

package com.connection;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;

public class Test implements Runnable{
    ServerSocket ss = null;
    public Test() throws Exception{
        ss = new ServerSocket(9999);
    }
    public void run(){
        try{
        Socket s = ss.accept();
        Writer w = new OutputStreamWriter(s.getOutputStream());
        w.write("Hello\n");
        w.flush();
        System.out.println("Server: wrote string 1");
        System.out.println("Server: sleeping...");
        Thread.sleep(5000);
        System.out.println("Server: woke up");
        w.write("Hello\n");
        w.flush();
        System.out.println("Server: wrote string 2");
        }catch(Exception e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) throws Exception{
        Thread server = new Thread(new Test());
        server.start();
        Thread client = new Thread(new TestClient());
        client.start();
    }
}
class TestClient implements Runnable{

    public void run() {
        try {
            Socket s = new Socket("localhost", 9999);
            // Comment out the below 4 lines to see the write exception on server
            BufferedReader r = new BufferedReader(new InputStreamReader(s.getInputStream()));
            System.out.println("Client: reading input...");
            String str = r.readLine();
            System.out.println(str);
            // Comment the *above* 4 lines to see exception on server
            Thread.sleep(1000);
            System.out.println("Client: woke up");
            s.close();
            System.out.println("Client: socket closed");
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}
...