views:

92

answers:

2

In my program I want to send some information to another computer with sockets. The first socket send some text throw the server and when the second socket receive this information it send a answer to the first socket. The problem is that another thread receive the answer and the only thing which I get is deadlock. This is the server side:

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);

                }
            }

This is the client side:

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){

        }
    }
A: 

Could you show us more of your code?

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

for starters. Judging by the little i'm seeing you have a problem with the order in which you're using them. As far as i can tell you have a inputSteram.readObject() method that has blocked somewhere waiting for a message from the other side.

pnt
Judging by the code you pasted below, i see several possible errors:1) As soon as you created an OutputStream object for the socket's output stream, you should flush it in order to send the client the stream headers. This will unblock the possibly blocked read..() method of the input stream of the client.
pnt
2)I see that as soon as you accept a connection, you create an object of type GameThread. Could you add the constructor body as a comment to your answer below? Possible problems you might have with that is simply creating an object (i'm assuming from a class which extends Thread) doesn't trigger anything unless explicitly state it. I think you meant new GameThread(..).start();
pnt
The problem is that the client have to wait for game request from other client. Of course he can start game manually. A client can request from the display thread the current user list from the server. This occurs race condition of the threads and the method have to wait the client thread to receive the list and after that to return it. In this game there are to many request from the display thread that's why I don't want to use a thread in the client. But here comes the problem of waiting for a request to play. This is my big problem and I will be very thankful if anyone help me with it.
Jordan Borisov
A: 

Here is the sendRequest method:

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

The client socket is created in the class Server

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

and it is put in hashmap when the user pass the login level:

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()+"");
            }

I thing I know what is the reason of the deadlock but I can't solve it. When the first user send the information to the other user he wait for response. Of course the other user send a response but this response is handle from other thread. So the deadlock is from a read method which block the thread. How can I send information from one socket to another without deadlock?

public GameThread(Socket socket, DatabaseManager databaseManager) {
    this.socket = socket;
    this.databaseManager = databaseManager;
    parser = new RequestParser(); 
    authorizationControl = new AuthorizationControl(databaseManager);
    communication = new SocketCommunication(socket);
    start();
}
Jordan Borisov
Do not enter additional information as an "answer" as you have done here, you should edit your original question to include this information.
Mystere Man