Многопоточный Java-сервер, ошибка исключения сокета - PullRequest
0 голосов
/ 07 января 2019

Настройка многопоточного сервера для назначения. Кажется, что поток вывода сокета не распознает источник - по крайней мере, это то, что я собираю из возвращенной ошибки.

когда я вызываю метод run () в моем классе Runnable RequestHandlerThread, все хорошо. Насколько я понимаю, это не многопоточность. когда я создаю новый поток и передаю ему свой RequestHandlerThread как исполняемый файл и пытаюсь запустить () поток - я получаю следующую ошибку:

java.net.SocketException: Socket is closed
    at java.net.Socket.getOutputStream(Unknown Source)
    at RequestHandlerThread.run(RequestHandlerThread.java:25)
    at java.lang.Thread.run(Unknown Source)

Basically I think I have a misconception of threads. 

//CHATSERVER CODE

import java.net.*;
import java.io.*;
import java.util.*;



public class ChatServer3 {
    public static void main(String[] args) throws IOException {

        if (args.length != 1) {
            System.err.println("Usage: java EchoServer <port number>");
            System.exit(1);
        }

        int portNumber = Integer.parseInt(args[0]);
        ServerSocket serverSocket = new ServerSocket(portNumber);
        System.out.println("Server3 is up and running on port : " + portNumber);

        while(true) {

            try (       
                Socket clientSocket = serverSocket.accept();    


            ) {
                System.out.println("Connection to Server3 has been established");
                new Thread(new RequestHandlerThread(clientSocket)).start();

                System.out.println("this");
            } catch (IOException e) {
                System.out.println("Exception caught when trying to listen on port "
                    + portNumber + " or listening for a connection");
                System.out.println(e.getMessage());

            }
        }

    }
}

// REQUESTHANDLER THREAD CODE

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

public class RequestHandlerThread implements Runnable {

    Socket socket;
    PrintStream out;
    Scanner in;

    public RequestHandlerThread(Socket socket)  {
        this.socket = socket;

    }

    @Override
    public void run() {

        String inputLine;
        try {
            out = new PrintStream(socket.getOutputStream());                   
            in = new Scanner(new InputStreamReader(socket.getInputStream()));   
            while ((inputLine = in.nextLine()) != null) {
                out.println("Server3:"+inputLine);
            }
            out.close();
            in.close();
        } catch (IOException e) {

//***************************************************************
            //THIS IS WHERE THE Socket EXception error is Generated
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}


//CHAT CLIENT CODE

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

public class ChatClient {
    public static void main(String[] args) throws IOException {

        if (args.length != 2) {
            System.err.println(
                "Usage: java EchoClient <host name> <port number>");
            System.exit(1);
        }

        String hostName = args[0];
        int portNumber = Integer.parseInt(args[1]);
        Socket echoSocket = new Socket(hostName, portNumber);
        System.out.println("Connection to server :" + hostName + " on port : " +portNumber );
        try (

            PrintWriter out = new PrintWriter(echoSocket.getOutputStream(), true);
            BufferedReader in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
            BufferedReader stdIn = new BufferedReader( new InputStreamReader(System.in))
        ) {
            String userInput;
            while ((userInput = stdIn.readLine()) != null) {
                if(userInput.equals(".quit")) {
                    System.out.println("Connection terminated by CLIENT");
                    break;
                }
                out.println(userInput);

                System.out.println( in.readLine());
            }
        } catch (UnknownHostException e) {
            System.err.println("Don't know about host " + hostName);
            System.exit(1);
        } catch (IOException e) {
            System.err.println("Couldn't get I/O for the connection to " +
                hostName);
            System.exit(1);
        } 
    }
}

Я ожидал, что потоки будут созданы и запущены одновременно, так что к серверу одновременно могут быть подключены несколько клиентов. Но я не могу на самом деле «запустить» потоки правильно

1 Ответ

0 голосов
/ 08 января 2019

clientSocket передается в поток, который запущен, но основной цикл использует try-with-resources, который закрывает clientSocket. Таким образом, поток обработчика пытается использовать его, но он был закрыт (в какой-то момент) основным потоком. Попробуйте что-то вроде этого:

Socket clientSocket = null;
try {       
    clientSocket = serverSocket.accept();  // not automatically closed  
    ...
} catch (IOException e) {
   ...
   clientSocket.close();   // in case there is an exception from the main loop
}

Но теперь поток обработки будет отвечать за закрытие сокета. out и in могут находиться в пределах try-with-resources, поэтому их не нужно закрывать вручную, и, наконец, блок для закрытия вручную socket.

...