これは非常に簡単なはずですが、明らかに基本的な理解が欠けています。シンプルなクライアントサーバーアプリケーションがあります
サーバ:
public class GameServer{
private Socket clientSocket;
private ServerSocket serverSocket;
private ArrayList<ObjectOutputStream> oosPlayers=new ArrayList<ObjectOutputStream>();
public static void main(String args[]){
GameServer server = new GameServer();
server.startGame();
}
public void startGame(){
try{
serverSocket = new ServerSocket(10008);
System.out.println("Server started at:" + serverSocket);
while(true){
System.out.println("Server: Waiting for client requests...");
clientSocket=serverSocket.accept();
System.out.println("Server: Client connection accepted at:"+clientSocket);
//remember player's output stream
oosPlayers.add(new ObjectOutputStream(clientSocket.getOutputStream()));
//read data from clients
Thread receiverThread = new Thread(new DataReceiver());
receiverThread.start();
}
}
catch(IOException ex){
System.out.println(ex.getMessage());
}
}
public class DataReceiver implements Runnable{
public void run(){
try{
String mess;
ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream());
while((mess=(String)ois.readObject()) != null){
System.out.println("Server: "+mess);
send();
}
}
catch(Exception ex){ System.out.println(ex.getMessage()); }
}
public void send(){
for (ObjectOutputStream oos : oosPlayers){
try{
oos.writeObject(new String("There is "+oosPlayers.size()+" player(s) at the board"));
oos.flush();
}
catch(Exception ex){ System.out.println(ex.getMessage()); }
}
}
}
}
クライアント:
public class GameClient implements ActionListener{
private Socket socket;
private ObjectInputStream ois;
private ObjectOutputStream oos;
private JButton button;
public static void main(String args[]){
GameClient client = new GameClient();
client.drawBoard();
}
public void drawBoard(){
JFrame frame = new JFrame("A game");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
button = new JButton("Send");
button.addActionListener(this);
configureConnection();
Thread receiverThread = new Thread(new DataReceiver());
receiverThread.start();
frame.getContentPane().add(new JPanel().add(button));
frame.setSize(200,200);
frame.setVisible(true);
}
public void configureConnection(){
try{
socket = new Socket("127.0.0.1", 10008);
ois = new ObjectInputStream(socket.getInputStream());
oos = new ObjectOutputStream(socket.getOutputStream());
}
catch(Exception ex) { System.out.println(ex.getMessage()); }
}
public void actionPerformed(ActionEvent ev){
if (ev.getSource()==button){
try{
oos.writeObject(new String("Some data from client"));
oos.flush();
}
catch(Exception ex){ System.out.println(ex.getMessage()); }
}
}
public class DataReceiver implements Runnable{
public void run(){
try{
String mess;
while((mess=(String)ois.readObject())!= null){
System.out.println("Client:"+mess);
}
}
catch(Exception ex){ System.out.println(ex.getMessage()); }
}
}
}
私の質問は、両側のreceiverThreadに関するものです。ObjectInputStreamからの読み取り中に(RUN メソッドで) WHILE を使用すると、サーバーはクライアントの要求をリッスンし、それらをすべてのObjectOutputStreamに適切にディスパッチします。このWHILEをIFに変更すると、データは各クライアントごとに 1 回だけサーバーから読み取られます (そして送信されます)。同じことがクライアントの WHILE/IF にも当てはまります。
私の理解では、receiverThreadを実行すると、WHILE でスレッドが何らかの形で停止し、入力ストリームからの読み取りが続行されますが、IF を使用するとスレッドが終了します (したがって、読み取りプロセスが停止します)。WHILE 条件が満たされていなくても、つまり最初は (まだクライアントが接続されていない)、receiverThreadが生きている可能性はありますか。同じことが、receiverThread が既にデータを読み取り、ストリームに何も残っていない場合にも発生します。
この基本的な問題について説明をいただければ幸いです。
よろしくマルシン