1

我正在尝试在同一进程上启动服务器和客户端线程,但似乎服务器线程正在阻塞客户端线程(反之亦然)。我不允许在这些线程之间使用任何全局变量(如信号量或互斥锁,因为客户端和服务器线程是由我无权访问的上层启动的)。

我在这里发现了一个类似的问题,但它仍然使用两个不同的过程(两个主要功能)。

这是我的代码示例

服务器代码:

public class MyServer implements Runnable{

    ServerSocket server;
    Socket client;
    PrintWriter out;
    BufferedReader in;

    public MyServer() throws IOException{
        server = new ServerSocket(15243, 0, InetAddress.getByName("localhost"));
    }

    @Override
    public void run() {
        while(true){
            try {

                ArrayList<String> toSend = new ArrayList<String>();

                System.out.println("I'll wait for the client");
                client = server.accept();
                out = new PrintWriter(client.getOutputStream(), true);
                in = new BufferedReader(new InputStreamReader(client.getInputStream()));

                String inputLine;
                while((inputLine = in.readLine()) != null){
                    toSend.add("answering : "+inputLine);
                }

                for(String resp : toSend){
                    out.println(resp);
                }

                client.close();
                out.close();
                in.close();

            } catch (IOException ex) {
            }

        }
    }
}

和客户端代码:

public class MyClient implements Runnable{

    Socket socket;
    PrintWriter out;
    BufferedReader in;

    public MyClient(){
    }

    @Override
    public void run() {
        int nbrTry = 0;
        while(true){
            try {
                System.out.println("try number "+nbrTry);
                socket = new Socket(InetAddress.getByName("localhost"), 15243);

                out = new PrintWriter(socket.getOutputStream(), true);
                in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

                out.println("Hello "+nbrTry+" !! ");

                String inputLine;
                while((inputLine = in.readLine()) != null){
                    System.out.println(inputLine);
                }
                nbrTry++;
            } catch (UnknownHostException ex) {
            } catch (IOException ex) {
            }
        }
    }
}

以及启动这些线程的假定上层阶级:

public class TestIt {

    public static void main(String[] argv) throws IOException{
        MyServer server = new MyServer();
        MyClient client = new MyClient();
        (new Thread(server)).start();
        (new Thread(client)).start();
    }
}

它给了我作为输出:

I'll wait for the client
Try number 0

它卡在这里。我应该怎么做才能保持服务器和客户端代码运行?谢谢你。

4

2 回答 2

1

我愿意回答你的问题,但基本上你需要更仔细地思考你的逻辑。

MyServer.java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class MyServer implements Runnable {

  ServerSocket server;

  public MyServer() throws IOException {
    server = new ServerSocket(15243, 0, InetAddress.getByName("localhost"));
  }

  @Override
  public void run() {
    while (true) {
      try {
        // Get a client.
        Socket client = server.accept();

        // Write to client to tell him you are waiting.
        PrintWriter out = new PrintWriter(client.getOutputStream(), true);
        out.println("[Server] I'll wait for the client");
        // Let user know something is happening.
        System.out.println("[Server] I'll wait for the client");

        // Read from client.
        BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
        String inputLine = in.readLine();

        // Write answer back to client.
        out.println("[Server] Answering : " + inputLine);

        // Let user know what it sent to client.
        System.out.println("[Server] Answering : " + inputLine);

        in.close();
        out.close();
        client.close();
      } catch (Exception e) {

      }
    }
  }
}

我的客户端.java

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

public class MyClient implements Runnable {

  Socket socket;
  PrintWriter out;
  BufferedReader in;

  public MyClient() throws UnknownHostException, IOException {
  }

  @Override
  public void run() {
    int nbrTry = 0;
    while (true) {
      try {
        // Get a socket
        socket = new Socket(InetAddress.getByName("localhost"), 15243);

        // Wait till you can read from socket.
        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String inputLine = in.readLine();
        //inputLine contains the text '[Server] I'll wait for the client'. means that server is waiting for us and we should respond.

        // Write to socket
        out = new PrintWriter(socket.getOutputStream(), true);
        out.println("[Client] Hello " + nbrTry + " !! ");

        // Let user know you wrote to socket
        System.out.println("[Client] Hello " + nbrTry++ + " !! ");

      } catch (UnknownHostException ex) {
      } catch (IOException ex) {
      }
    }
  }
}

TestIt.java

import java.io.IOException;

public class TestIt {

  public static void main(String[] argv) throws IOException {
    MyServer server = new MyServer();
    MyClient client = new MyClient();
    (new Thread(server)).start();
    (new Thread(client)).start();
  }
}
于 2013-03-19T14:20:32.723 回答
1

您的客户端发送一个字符串,然后读取直到流用完:

                while((inputLine = in.readLine()) != null){

我记得 BufferedReader.readLine() 只在流的末尾返回 null 。在流上,它将阻塞直到输入可用

您的服务器接收直到流用完,然后发回其响应。

发送一行后,您现在拥有:

  • 您的客户正在等待回复。
  • 您的服务器仍在等待来自客户端的更多数据。但它不会发送任何东西,直到客户端的流结束(这永远不会发生,因为客户端正在等待您的响应)。
于 2013-03-19T14:24:45.063 回答