2010-02-28 77 views
1

在我的节目,我希望将一些信息发送到另一台计算机上的插座。第一个套接字发送一些文本抛出服务器,当第二个套接字接收到这个信息时,它向第一个套接字发送一个答案。问题是另一个线程收到答案,我得到的唯一东西是死锁。 这是服务器侧:线程,插座和流

else if(msgArray[0].compareTo("game_request") == 0){ 
       if(userMap.containsKey(msgArray[1])){ 
        Socket socketPlayerTwo = userMap.get(msgArray[1]); 
        otherPlayer = msgArray[1]; 
        sendResult(socketPlayerTwo, "game_offer?"+username); 
        Boolean willPlay =Boolean.valueOf(recieveRequest(socketPlayerTwo).split("?")[1]); 
        if(willPlay) 
         playingUser.put(username,msgArray[1]); 
        sendResult(socket, "game_accept?"+willPlay); 

       } 
      } 

这是客户端:

private void showGameRequest(String usernameOther) { 
     try{ 
      int status = GameWindow.getInstance().showNotification("Game Offer","The user " + usernameOther + " offers you a game!\nDo you agree?",SWT.ICON_QUESTION|SWT.YES|SWT.NO); 
      if (status == SWT.YES){ 
       otherPlayer = usernameOther; 
       sendRequest("send_message_to_user?user="+usernameOther+"&value=true"); 
       GameWindow.getInstance().getDisplay().asyncExec(new Runnable() { 

        @Override 
        public void run() { 
         GameWindow.getInstance().startNewGame(); 

        } 
       }); 
      } 
      else 
       sendRequest("send_message_to_user?user="+usernameOther+"&value=false"); 
      } 
     catch (IOException exc){ 

     } 
    } 

这里是sendRequest方法:

private void sendResult(Socket socket,String request) throws IOException{ 
    DataOutputStream writer = new DataOutputStream(socket.getOutputStream()); 
    writer.writeUTF(request); 
    writer.flush(); 
} 

客户端套接字中所创建的类服务器

while (true) { 
     try { 
      Socket socket = serverSocket.accept(); 
      new GameThread(socket,databaseManager); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

,它被放在HashMap中,当用户通过登录级别:

if(msgArray[0].compareTo("user_info") == 0){ 
       Integer flagUser = -1; 
       String[] userInfo = {msgArray[1].substring(msgArray[1].indexOf("=") + 1, msgArray[1].indexOf("&")),msgArray[1].substring(msgArray[1].lastIndexOf("=")+ 1, msgArray[1].indexOf(";"))}; 
       Boolean status = databaseManager.checkUser(userInfo[0], userInfo[1]); 
       if(status){ 
        if(!userMap.containsKey(userInfo[0])){ 
         userMap.put(userInfo[0], socket); 
         username = userInfo[0]; 
         flagUser = 0; 
        } 
        else 
         flagUser = 1; 
       } 
       sendResult(socket, "user_info_status?"+flagUser.toString()+""); 
      } 

我的事情我知道了什么是死锁的原因,但我解决不了。当第一个用户将信息发送给另一个用户时,他等待响应。当然其他用户发送一个响应,但这个响应是来自其他线程的句柄。所以死锁是来自阻塞线程的读取方法。我怎样才能从一个套接字发送信息到另一个没有死锁?

public GameThread(Socket socket, DatabaseManager databaseManager) { 
    this.socket = socket; 
    this.databaseManager = databaseManager; 
    parser = new RequestParser(); 
    authorizationControl = new AuthorizationControl(databaseManager); 
    communication = new SocketCommunication(socket); 
    start(); 
} 
+0

你需要显示sendRequest将(),sendResult()函数,以及如何套接字被创建并放在中userMap。 – beny23 2010-02-28 15:08:40

回答

0

你能告诉我们更多你的代码吗?

sendResult(socketPlayerTwo, "game_offer?"+username); 
recieveRequest(socketPlayerTwo); 
sendRequest("send_message_to_user?user="+usernameOther+"&value=true"); 

初学者。 由小我看到你有你使用它们其中的顺序有问题来看。据我可以告诉你有一个inputSteram.readObject()方法阻塞某处等待来自另一端的消息。

+0

评判你所粘贴下面的代码,我看到几个可能的错误: 1)一旦你创建了套接字的输出流的OutputStream对象,你应该为了向客户端发送流头冲洗掉。这将解除阻塞客户端输入流的可能被阻止的读取..()方法。 – pnt 2010-03-01 22:50:25

+0

2)我看到,只要你接受一个连接,创建类型GameThread的对象。你可以添加构造函数体作为你的答案在下面的评论?你可能遇到的问题是简单地创建一个对象(我从一个扩展了Thread的类中假设)不会触发任何东西,除非明确声明它。我认为你的意思是 new GameThread(..)。start(); – pnt 2010-03-01 22:50:41

+0

问题是客户端必须等待来自其他客户端的游戏请求。当然,他可以手动开始游戏。客户端可以从显示线程向服务器请求当前用户列表。这会发生线程的竞争条件,并且该方法必须等待客户端线程接收列表,然后再返回它。在这个游戏中有很多来自显示线程的请求,这就是为什么我不想在客户端使用线程。但是等待请求播放的问题就出现了。这是我的大问题,如果有人帮助我,我将非常感激。 – 2010-03-02 14:21:00