Client Threads Server

6

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

You're supposed to do this:

  

The server should work in multithreading, having for each active connection two threads, which we will call in and out:

     
  • in for receiving client messages (input stream)   This thread is blocked waiting for messages from the client. Messages that the server receives should be stored in a memory structure. When a given user has new messages, if this is online, the thread out associated with your connection should be notified in order to process the delivery of the messages.
  •   
  • out for delivery of messages and notifications to customers (output stream)   This thread is on hold, making it active when there are new messages or delivery notifications for the connection 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();
        }   
    }
}
    
asked by anonymous 15.12.2015 / 15:37

1 answer

6

Create the two threads

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

Basically, you need ListenerSocket (with only n ) to redo the in and another class to deal with 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 readObject method, so the first part of the problem will be satisfied.

Use a suitable memory structure

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

You store% s of user% s, but this is wrong. The% s of user% s must be managed by the OutputStream threads created for each of them.

My suggestion is that you use OutputStream to avoid synchronization problems, otherwise you will have to use out whenever you access ConcurrentHashMap . Check with your teacher if you can use this.

In each map item, there should be a message queue that should be delivered to the user. You can use synchronize with manual synchronization or HashMap for automatic synchronization.

Then your map would look something like:

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

How message synchronization can happen

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

In the output thread, you should then retrieve the list and call the ArrayDeque method from the list so that the thread is blocked. If it is ArrayBlockingQueue , just call the wait() method and the lock will occur automatically until a message is received.

In the reading thread, when you receive a message, you scroll through all the map values, sort of like you are doing, add the message to the queue, and then call the method ArrayBlockingQueue from the list to wake threads locked by take() . If it is nofityAll() you do not have to do anything because the wait() method will automatically return.

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

Signaling the output of a user

When the user exits, you have to interrupt the two threads. This means that you need to wake them up and flag them in some way to get them out of the loop.

In case of input it is easy because you will get the message, warn the users and exit the loop.

In the case of output, you can put a flag in the message saying that it is an outgoing message and thus exit the loop without sending the message.

Considerations

Even with the implementation misconceptions, I do not think you're far from making a good implementation.

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

    
16.12.2015 / 02:42