2011-05-16 137 views
2

我的Java程序出现问题。它在服务器和许多客户端之间有一个套接字连接。这里是服务器(这涉及问题的部分):Java,使用套接字连接发送消息的问题

private static ArrayList<ParallelServer> clientConnected = new ArrayList<ParallelServer>(); 


public Server(int port) { 
    this.port = port; 
    if (!startServer()) 
     JOptionPane.showMessageDialog(new JFrame(""), 
       "Error!", "ERROR!", 
       JOptionPane.ERROR_MESSAGE); 
} 

private boolean startServer() { 
    try { 
     server = new ServerSocket(port); 
     loadDatabase(); 
    } catch (IOException ex) { 
     ex.printStackTrace(); 
     return false; 
    } catch (ClassNotFoundException e) { 
     e.printStackTrace(); 
    } 
    return true; 
} 

public void runServer() { 
    while (true) { 
     try { 
      client = server.accept(); 
      ParallelServer pServer = new ParallelServer(client); 
      clientConnected.add(pServer); 
      Thread thread = new Thread(pServer); 
      thread.start(); 
     } catch (IOException ex) { 
      ex.printStackTrace(); 
     } 
    } 
} 


public static void sendBroadcast(String username) throws IOException { 
    for(int i = 0; i < clientConnected.size(); i++) 
     clientConnected.get(i).sendAnswer("@change," + username); 
} 

并行服务器是:

private Socket client; 
    private InputStreamReader inputstreamreader; 
    private BufferedReader bufferedreader; 
    private PrintWriter printwriter; 

    public ParallelServer(Socket client) { 
     this.client = client; 
    } 

    public void run() { 
     try { 
      inputstreamreader = new InputStreamReader(client.getInputStream()); 
      bufferedreader = new BufferedReader(inputstreamreader); 
      printwriter = new PrintWriter(client.getOutputStream(), true); 
      String lineread = ""; 

      while (client.isConnected()) { 
       lineread = bufferedreader.readLine(); 
       doCommand(lineread); 
      } 
     } catch (UnknownHostException unhe) { 
     } catch (InterruptedIOException intioe) { 
     } catch (IOException ioe) { 
     } catch (ClassNotFoundException e) { 
      e.printStackTrace(); 
     } 
    } 

    public void sendAnswer(String answer) throws IOException { 
     printwriter = new PrintWriter(client.getOutputStream(), true); 
     printwriter.println(answer); 
     printwriter.flush(); 
    } 

,这里是客户端:

private String serverurl = "localhost"; 
private int serverport = 7777; 
private PrintWriter printwriter; 
private InputStreamReader inputstreamreader; 
private BufferedReader bufferedreader; 
private Socket server; 

public Client() { 
    server = null; 
    try { 
     server = new Socket(serverurl, serverport); 
     server.setSoTimeout(5000); 
    } catch (UnknownHostException unhe) { 
     System.out.println("UnknownHostException: " + unhe.getMessage()); 
    } catch (InterruptedIOException intioe) { 
     System.out.println("Timeout while attempting to establish socket connection."); 
    } catch (IOException ioe) { 
     JOptionPane.showMessageDialog(new JFrame(),"Unable to reach the server!","ERROE!",JOptionPane.ERROR_MESSAGE); 
    } 
} 

public String sendCommand(String command) throws IOException { 
    if(server == null) { 
     try { 
      server = new Socket(serverurl, serverport); 
      server.setSoTimeout(5000); 
     } catch (UnknownHostException unhe) { 
      System.out.println("UnknownHostException: " + unhe.getMessage()); 
     } catch (InterruptedIOException intioe) { 
      System.out.println("Timeout while attempting to establish socket connection."); 
     } catch (IOException ioe) { 
      JOptionPane.showMessageDialog(new JFrame(),"Unable to reach the server!","ERROR!",JOptionPane.ERROR_MESSAGE); 
     } 
    } 
    if(server != null) { 
     printwriter = new PrintWriter(server.getOutputStream(), true); 
     printwriter.println(command); 
     printwriter.flush(); 
     inputstreamreader = new InputStreamReader(server.getInputStream()); 
     bufferedreader = new BufferedReader(inputstreamreader); 

     return bufferedreader.readLine(); 
    } 
    else 
     return "@serverProblem"; 
} 

该方案是一个简单的在线游戏轮流。玩家的轮流是用队列创建的,当玩家轮到他时,服务器发送一条广播消息,其中说:“现在是'玩家1'转。” (例如)。我的问题是,当客户收到消息时,它就像添加了答案“现在是'玩家1'转。”到它将收到的下一条消息。就我而言:当一名球员轮到他时,他会发送“@ passTurn,username”。 ParallelServer类从队列中轮询它,将它放在队列底部,发送客户端“@ok”告诉它轮到已成功更改,并通知服务器类发送广播消息。然后,当同一客户尝试做进一步行动时,它会考虑“现在是'玩家1'转。”作为服务器给它的答案。相反,我希望服务器和客户端能够一如既往地工作,当广播消息正常时,通知客户端没有任何附带影响。 我能做什么? 谢谢。

+0

您的输出是在控制台还是IDE?另外,你确定你没有看到之前被缓存的消息吗? – Vern 2011-05-16 01:20:02

+0

@Vern:我的输出是一个IDE。关于缓冲区,它发生这样的事情:客户端发送“@passTurn” - >服务器发送“@ok” - >客户端接收它 - >服务器然后发送“@ changeTurn,player1”(客户端什么都不做,因为它没有发送消息,而不是等待答案) - >客户端发送“@otherAction”并读取“@ changeTurn,player1”作为答案。 – Simon 2011-05-16 01:43:32

+0

那么,在那个消息交换的哪一点是失败? – Vern 2011-05-16 02:02:33

回答

1

你的双向信息传递机制应该是这个样子:

服务器:

Wait on any client InputStream 
if (broadcast) 
    broadcast_message() 
else 
    process_message() 

客户:

Receiving Thread: 
Wait on server broadcast 

Sending Thread: 
Wait on messages to be sent to server from the User Input 

这应该做的伎俩:)

希望能帮助到你。干杯!

+0

我不能用这种方式写服务器,因为在InputStream之后没有发送广播消息。我尝试按照您的建议组织客户端,创建一个新的线程来等待广播消息,但是bufferedreader已经搞乱了(我的想法是从两个不同的bufferedreader上的相同输入流中读取,但它不起作用) 。也许我应该尝试使用互斥锁来达到这个目的。 – Simon 2011-05-16 18:56:48

+0

用不断监听服务器的线程完成。使用if(bufferedreader.isReady())并每隔3秒读取一次答案,通信正常工作。无论如何,感谢给我使用两个不同线程的想法! :) – Simon 2011-05-17 01:54:10

+0

嘿,别担心!很高兴你设法让事情奏效,我总是乐于帮助!干杯! – Vern 2011-05-17 06:58:25