使用线程和套接字获取服务器响应

时间:2016-11-13 22:36:25

标签: java multithreading sockets

我正在构建连接到服务器并发送消息的客户端。我有那个部分,服务器正在收到消息,但我遇到的问题是让我的客户端侦听来自服务器的消息。基本上它就像一个聊天室,我将不得不向服务器发送消息,我的客户端也需要从服务器接收消息并在服务器发送时将其打印出来。

我没有构建服务器,或者无法访问服务器代码,但我确实知道服务器正常工作。下面是我对客户端的看法,SendThread工作正常,但是当我添加一个GetThread时,发送线程不再有效,所以我不能让2个线程工作,一个监听,一个发送。

Client.java

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

        // String name = args[0];
        String name = "Brandon";
        Socket socket = new Socket("localhost", 4688);
        Thread sendThread = new SendThread(socket, name);
        Thread getThread = new GetThread(socket);
        sendThread.start();
        getThread.start();
    }
}

SendThread.java

public class SendThread extends Thread {
    Socket socket;
    String name;
    SendThread(Socket s, String n) {
        socket = s;
        this.name = n;
    }

    public void run(){
        try{
            String message;
            PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);
            printWriter.println("connect Brandon");
            BufferedReader bufferedReaderFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            System.out.println(bufferedReaderFromClient.readLine());
            BufferedReader bufferedReader = new java.io.BufferedReader(new InputStreamReader(System.in));
            while(true) {
                String readerInput = bufferedReader.readLine();
                printWriter.println(name + ": " + readerInput);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

GetThread.java

public class GetThread extends Thread {
    Socket socket;

    GetThread(Socket s) {
        socket = s;
    }

    public void run(){
        try{
            String message;
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            while((message = bufferedReader.readLine()) != null) {
                System.out.println("Incoming: " + message);
            }
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

2 个答案:

答案 0 :(得分:1)

不要创建第二个BufferedReader。在插座的使用寿命中使用相同的一个。您正在丢失第一个读者已缓冲的数据。

如果readLine()返回null,则需要中断读取循环。

答案 1 :(得分:-1)

看起来像竞争条件。 readLine()阻塞,直到发送一条消息,当发生这种情况时,GetThread或SendThread将抓住它,让另一个再次等待。如果您需要两个线程中的消息,为了避免并发问题,您应该考虑使用监视器:

public class Monitor {
    private String msg;
    private boolean hasMsg = false;

    public synchronized void newMsg(String msg) {
        this.msg = msg;
        hasMsg = true;
        notifyAll();
    }

    public synchronized String getMsg() {
        try {
            while (!hasMsg) wait();
        } catch (InterruptedException e) {};

        hasMsg = false;
        return msg;
    }
}

public class Client {
    // ...
    Monitor m = new Monitor();
    Thread sendThread = new SendThread(m, socket, name);
    Thread getThread = new GetThread(m, socket);
    // ...
}

public class GetThread extends Thread {
    private Monitor monitor;
    private Socket socket;
    public GetThread(Monitor m, Socket s) {
        monitor = m;
        socket = s;
    }

    public void run() {
        // ...
        while((message = bufferedReader.readLine()) != null) {
            monitor.newMsg(message);
            System.out.println("Incoming: "+message);
        }
        // ...
    }
}

public class SendThread extends Thread {
    private Socket socket;
    private Monitor monitor;
    private String name;
    public SendThread(Monitor m, Socket s, String n) {
        monitor = m;
        socket = s;
        name = n;
    }

    public void run() {
        // ...
        String readerInput = monitor.getMsg();
        printWriter.println(name + ": "+readerInput);
        // ...
    }
}