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