Java客户端问题< - >服务器套接字

时间:2017-03-20 20:13:40

标签: java multithreading sockets

这就是我想要实现的目标:

有客户端和服务器套接字。客户端套接字将向服务器发送消息(例如"add:2:3" to add 2 and 3等)。服务器应该回答一个答案。当答案到达时,客户端可以发送附加消息(如"subtract:5:8" to subtract 5 from 8)等...因此客户端将发送消息,然后它将得到响应,然后它将发送下一条消息并获得响应我从命令行发送消息。

这就是我现在所拥有的,但它不起作用:

//服务器代码

public class MT extends Thread{

    private Socket sock;
    private BufferedReader rd;
    private OutputStreamWriter wr;

    private Client client;

    public MT(Socket sock) throws IOException {
        this.sock= sock;
        rd = new BufferedReader(new InputStreamReader(sock.getInputStream()));
        wr = new OutputStreamWriter(sock.getOutputStream());
        wr.write("You are welcome"  + "\n");
        wr.flush();
    }

    public void run(){
        try{
            while(true){
                String command = reader.readLine(); 
                // Will process data here and then send results to client
                // At the moment i just want to send the message back to client
                wr.write(command + "\n"); // send results to client
                    }
                }
            }
        }catch(IOException ex){
            System.err.println("Problem reading data from client");
        }
    }

}


public class MyServio {

    public static void main(String[] args) {

        try(ServerSocket server = new ServerSocket()){

            server.bind(new InetSocketAddress("0.0.0.0", 4444));
            System.out.println("Listening...");

                try{
                    while(true){
                    Socket con = server.accept();

                    Thread a = new MT(con);
                    a.start();
                }
                }catch(IOException ex){
                    System.err.println("Problem...");
                }

        }catch(IOException ex){
            System.err.println("Server Issues");
        }
    }

}

//客户端

对于客户端,我决定使用两个线程来读取和写入服务器

public class MyRead extends Thread{

    private BufferedReader r;

    public ReadFromServer(BufferedReader r){

            this.r = r;
    }

    @Override
    public void run() {
            StringBuilder m = new StringBuilder();
            try {
                while(true){
                    message.append(r.readLine());
                    System.out.println(m);
                }
            } catch (IOException e) {
                System.out.println("Problem in MyRead");
                e.printStackTrace();
            }


    }

}




public class MyWrite extends Thread{

    private OutputStreamWriter w;
    Scanner sc;

    public WriteToServer(OutputStreamWriter w){
            this.w = w; 
            sc = new Scanner(System.in);
    }

    @Override
    public void run() {

        try {
            while(true){ 
               System.out.print("Type message: ");
               String msg = sc.nextLine(); 
               w.write(msg + "\n");
               w.flush();
        }
        } catch (IOException e) {
            System.out.println("Problem in MyWrite");
            e.printStackTrace();
        }

    }
}




public class CSock {

    private OutputStreamWriter w;
    private BufferedReader r;

    public ClientSocket() {}

    public void do(){

        InetAddress ad = null;
        try {
            ad = InetAddress.getByName("127.0.0.1");
        } catch (UnknownHostException e) {
            System.err.println("Error InetAddress");
        }
        try (Socket s = new Socket(addr, PORT)) {

            System.out.println("Server connecting...");


            StringBuilder message = new StringBuilder();

            r = new BufferedReader(new InputStreamReader(s.getInputStream()));
            w = new OutputStreamWriter(s.getOutputStream());

            message.append(r.readLine()); // reads the welcome message from server
            System.out.println(message); 

          // I start the read and write threads so that the client can read and write message to the server 
            ReadFromServer rd = new ReadFromServer(r);
            WriteToServer wt = new WriteToServer(w);
            rd.start();
            wt.start();
        } catch (IOException ex) {
            System.err.println("problem connecting to server");
        }
    }

}




public class Main {

    public static void main(String[] args){

        ClientSocket clientSocket = new ClientSocket();
        clientSocket.do();

    }

}

我首先启动服务器,然后启动客户端,但客户端提供了一个例外:

Problem in MyRead
java.net.SocketException: socket closed
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:170)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at java.io.BufferedReader.fill(BufferedReader.java:161)
    at java.io.BufferedReader.readLine(BufferedReader.java:324)
    at java.io.BufferedReader.readLine(BufferedReader.java:389)
    at model.ReadFromServer.run(ReadFromServer.java:31)

异常中的最后一行表示代码中的message.append(reader.readLine());是问题所在。我不会在我的代码中的任何地方关闭套接字或输入流或输出流,但我得到了这个例外。

在以下行socket closed

中的MyWrite方法的run()课程中也会出现类似的writer.flush();例外情况

2 个答案:

答案 0 :(得分:1)

在此行的客户端

try (Socket s = new Socket(addr, PORT)) {

你告诉jvm它应该在执行try语句后关闭套接字。

这一行是从套接字的输出流创建一个阅读器。

 r = new BufferedReader(new InputStreamReader(s.getInputStream()));

这是创建一个从服务器读取的功能。

ReadFromServer rd = new ReadFromServer(r);

ReadFromServer是一个线程,在try-catch语句完成后可以自由执行。因此,当它执行reader.readLine()时,套接字将被关闭。

答案 1 :(得分:0)

您关闭了套接字,然后继续使用它。 try-with-resource语句关闭了套接字;你开始使用的两个线程继续使用它。