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

标签 java multithreading sockets

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

有客户端和服务器套接字。客户端套接字将向服务器发送一条消息(例如“add:2:3”添加2和3等)。服务器应该用答案进行响应。当答案到达时,客户端可以发送额外的消息(例如“subtract:5:8”从8中减去5)等...因此客户端将发送一条消息,然后它会得到响应,然后它将发送下一条消息并获得响应,等等。我从命令行发送消息。

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

//服务器代码

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()); 是问题所在。我没有在代码中的任何地方关闭套接字或输入流或输出流,但我得到了这个异常。

还在以下行 writer.flush 的 run() 方法中的 MyWrite 类中获得类似的 socket close 异常();

最佳答案

在客户端中这一行

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()时,套接字将关闭。

关于java - Java 客户端<-->服务器套接字的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42913119/

相关文章:

java - Google Apps 类到 JList

java - 无法从配置 XML 中的属性文件读取值

java - 单个页面上的 Websocket 数

c# - 如何使用 .NET Framework 获取所有事件的 TCP 连接(无非托管 PE 导入!)?

python - 如何使用 Python 流套接字作为代理?

java - 是否需要同步读取变量?

java - 更改 Lotus Notes 中的 "from"字段

java - android中将执行切换到主线程

c# - 是否双重检查锁定了我最干净的选项以确保任务被调用一次?

c# - Parallel.ForEach错误