Threads Server Client

Asked

Viewed 527 times

6

In the following class SocketServidor send a single thread with the out and the in, but this class is supposed to be able to send two threads when running.

You’re supposed to do this:

The server should work in multi-threading, having for each active connection two threads, which we will designate in and out:

  • in to receive messages from customers (input stream) This thread will be locked waiting for messages from the client. Messages that the server receives should be stored in a structure in memory. When a given user has new messages, if they are online, the thread out associated with their connection should be notified in order to process the delivery of the messages.
  • out to deliver messages and notifications to customers (output stream) This thread will be on hold, becoming active when there are new messages or message delivery notifications relating to the link user.

SocketServidor

public class SocketServidor extends Thread{
    private ServerSocket servidorSocket;
    private Socket socket;
    private static final int PORTA = 8080;

    //HashMap recurso partilhado! (sempre que invocarmos este recurso temos de fazer synchronized)

    private Map<String, ObjectOutputStream> utilizadores = new HashMap<String, ObjectOutputStream>();  //utilizadores da aplicacao (online!)


    public SocketServidor(){
        try {
            servidorSocket = new ServerSocket(PORTA);               
            System.out.println("Estabelecer ligação TCP/IP no porto: " + PORTA);
            System.out.println("A aguardar conexão do cliente...");

            while(true){                                                            
                socket = servidorSocket.accept();                                   

                new Thread(new ListennerSocket(socket)).start();                        
            }
        } catch (IOException e) {
            e.printStackTrace();
        }   
    }
}
  • 1

    And what is your doubt?

  • @Nilsonuehara is to do the server with multithreading, server with two threads one in and one out, is that what I do above is to send only one thread with the in and the out.

  • @Nilsonuehara and the in and out are supposed to give as described above, can help me?

1 answer

7


Create the two threads

The first thing wrong with the code is that it creates a single thread to handle in and out.

Basically, you need the ListenerSocket (with only one n) to re-read the in and another class to deal with the out.

For example:

new Thread(new ListenerSocket(socket.getInputStream())).start(); 
new Thread(new ReplierSocket(socket.getOutputStream())).start(); 

The listening thread is automatically blocked until you receive a message when you call the method readObject, then the first part of the problem will be satisfied.

Use a proper memory structure

In your code there is no memory structure that stores messages.

You store the OutputStreamusers, but this is wrong. The OutputStreamusers should be managed by threads out created for each of them.

My suggestion is that you use one ConcurrentHashMap to avoid synchronization issues, otherwise you will have to use synchronize whenever you access the HashMap. Check with your teacher if you can use this.

On each map item, there should be a queue of messages that should be delivered to the user. You can use ArrayDeque with manual synchronization or ArrayBlockingQueue for automatic synchronization.

So your map would be something like:

private Map<String, ObjectOutputStream> mensagensAEntregar = new HashMap<String, ArrayDeque<Mensagem>();

How message synchronization can happen

When creating threads, add an empty message queue to the message map.

In the output thread, you should then retrieve the list and call the method wait() of the list to block the thread. If ArrayBlockingQueue, just call the method take() and the lock will occur automatically until a message is received.

In the read thread, when you receive a message, you scroll through all the values of the map, more or less as you are doing, add the message in the queue and then call the method nofityAll() of the list to wake up the threads blocked by wait(). If it is ArrayBlockingQueue you don’t have to do anything because the method take() will automatically return.

Note that wait() and notify() or notifyAll() only work if you call on the same object.

Signaling the exit of a user

When the user leaves, you need to interrupt the two threads. This means that you need to wake them up and signal them somehow to get them out of the loop.

In case of input is easy as you will receive the message, warn users and exit the loop.

In the case of output, you can put a flag on the message saying it is an output message and so exit the loop without sending the message.

Considerations

Even with the mistakes of the implementation, I do not believe that you are far from being able to make a good implementation.

I suggest you rewrite your code by following my tips above and perhaps other tips from other users. Then you can edit your issue with the new code (without removing the first one) or even create other questions about more specific problems you face.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.