2010-02-28 74 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