1

サーバー スレッドとクライアント スレッドを同じプロセスで起動しようとしていますが、サーバー スレッドがクライアント スレッドをブロックしているようです (またはその逆)。これらのスレッド間でグローバル変数を使用することは許可されていません (クライアントとサーバー スレッドは、私がアクセスできない上位クラスによって起動されるため、セマフォやミューテックスなど)。

ここで同様の質問を見つけましたが、それでも 2 つの異なるプロセス (2 つの主な機能) を使用しています。

ここに私のコードのサンプルがあります

サーバーコード:

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) {

      }
    }
  }
}

MyClient.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 を返します。ストリームでは、入力が利用可能になるまでブロックされます

サーバーはストリームが使い果たされるまで受信し、その後応答を返します。

1行送信すると、次のようになります。

  • クライアントが応答を待っています。
  • サーバーはまだクライアントからのデータを待っています。ただし、クライアントからのストリームが終了するまで何も返信しません (クライアントが応答を待っているため、これは発生しません)。
于 2013-03-19T14:24:45.063 に答える