这一定很容易,但我显然缺少一些基本的理解。我有简单的客户端服务器应用程序
服务器:
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数据,则每个客户端仅从服务器读取(并发送)一次。这同样适用于客户端的 WHILE/IF。
我的理解是,当我运行receiverThread时,它以某种方式在 WHILE 停止线程并继续从输入流中读取,而使用 IF 让线程完成(从而停止读取过程)。尽管不满足 WHILE 条件,即最初(还没有客户端连接),但它使receiverThread保持活动状态,这怎么可能呢?在receiverThread 已经读取数据并且流中没有任何内容之后也会发生同样的情况。
希望能对这个基本问题做出一些解释。
问候马辛