ChatServer in java - java

I did a simple chatserver in the java ... I'm wondering about adding a username to a chat that you need to enter when you enter chat. Also, I do not understand how private messages are sent only to the addressee
If the destination is not logged in to the chat server, the error message should be sent to the sender
Each message sent by the server to the client must be accompanied by the name of the original sender and the time when the message was sent.
Java Code ---> https://dijaspora24.info/?page_id=4123

I am not going to show the implementation, since it's a big problem to solve here. However, I will give an idea of how to implement this.
I assume you know how to connect a client to a server (for example by using ServerSocket and Socket).
First, to add the username of a connected client, the server simply has to force the client enter a string to the server as the first thing when it connects to the server.
Second, create a Map to store all clients, where key is the username entered and value is the socket.
Third, when a client want to send a message to another client, some format must be used to send a string that is understandable by the server. When sending a string to another client, the username of the receiving client must be within the string. When the server receives the string, it extracts the username of the receiving client's username and locates the client in the Map by its key. As mentioned, the value of the Map element is the socket instance of the client you want to send to.
To make all of this possible, a thread must be used for each client that listens for input from each client.

Related

Sending requests and handling multiple threads talking to each other over sockets without interference

I'm creating a Java program, based on the client-server model in which I need the server and the client(s) to communicate.
More specifically I need them to "give orders" to each other or request things, and transfer data inside those orders/requests, you can see what I'm trying to achieve looks something like a method, but instead of happening locally, those "methods" are called by one side and executed by the other.
For instance a possible scenario is:
The server is listening for orders
The client tries to authenticate
and sends username and password to the server
The server receives
the authentication request, controls whether the username and
password are correct and reports back to the client
The client is
now authenticated
The server is once again listening for orders
Now, my first idea was to use DataInputStream and DataOutputStream, sending requests under the form of strings, for instance, if I wanted the client to request authentication I would do something like this:
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.writeUTF("requestAuth");
dos.writeUTF(username);
dos.writeUTF(password);
and the server:
DataInputStream dis = new DataInputStream(socket.getInputStream());
if(dis.readUTF().equals("requestAuth")){
String username = dis.readUTF();
String password = dis.readUTF();
//Check whether they're correct or not bla bla bla
}
This doesn't seem like the best option to me, I think there's better ways to do this but I just don't know how, I already searched for a better solution but found nothing.
Another problem that arised is that I need both the server and the client to be able to send those requests simultaneously and these requests can be sent anytime, asynchronously.
For instance: let's say the client is authenticating, it's sending the username, password, etc... but meanwhile the server wants to check if the client is still connected because a Thread is doing it every second, how can I make sure each information is delivered in the right place without the stream clogging up or threads receiving unwanted data? If the client is waiting to know whether the username and password are correct, I don't want to clog it up with the request of the other thread that's doing something completely different.
Basically: my client/server program can be multithreaded, can sockets too without things getting messy? Can I have thread ServerA communicating with thread ClientA, and thread ServerB communicating with thread ClientB without interferring with each other? Can I have multiple streams from the same socket and work on them separately?

How could I send a string message to a specific client from a server using sockets in java?

I want to send data to my connected clients, but I want to send the message only to one specific user. I don't know how to accomplish this. Do I have to use the client's IP address or what? I'm programming in Java with sockets.
you need to add connected connection in some collection.
Socket client = serverSocket.accept();
map.put("someKey", client);
when you have to send message to any specific client. just get his connection from map by giving its key.
Socket clnt = map.get("someKey");
// further processing.
in c# you can use dictionary in place of maps.
You have to keep track of the clients that connect to your server. Most likely using a client ID with a Key/Value collection (try looking up Map).

How to enclose the username to the message and then get it from there?

I'm sending messages using java.net. And the server part works with many clients and depending on from what client I receive the message I choose the way to process the message. As I think I need to encolose the username to the message and then get it from there making the rest of the message as it was and sending it for the proceissing. How to do this? How such issues are usually resolved?
When you then receiver data, you can identify the client based on the sender's IP-address. If you still need the clientname, then send it as part of the first message after opening the connection. You can then relate the clientname with its IP-address.

connect to a lacewing server chat

I'm trying to make a port of a chat program a friend of mine made with lacewing and multimedia fusion 2 for android device.
I've managed to create a socket connecting to the listening socket of the server successfully, but I cannot seem to be able to send data to login and enter the chat. The login for now just requires a name, but even if I send a String of data, the server doesn't seem to reply or accept that data to get me over the channel.
I know I could easily port this with other way like using the NDK of the multimedia fusion 2 exporter, but I just want to figure out how this works
PS: I'm using Java and libgdx for the development
You need to read the liblacewing relay protocol:
https://github.com/udp/lacewing/blob/0.2.x/relay/current_spec.txt
On initial connection, you have to send byte 0 to identify that you are not an HTTP client. After this, you can exchange normal protocol messages.
The first message you need to send is the connection request (which may be denied by the server with a deny message). This would be:
byte 0 (2.1.0 request)
(1.2 size)
byte 0 (2.1.0.0 connection request)
string "revision 3" (2.1.0.0 connection request -> version)
When the server responds with response 0 (2.2.0.0 Connect), you then have to set a name before you may join any channels. This is done with message 2.1.0.1 SetName, which is the same structure as above but instead of 2.1.0.0's byte 0, it is 2.1.0.1's byte 1, followed by the name as a string instead of the protocol version.
The server should then respond with 2.2.0.1 SetName, assuming it accepted your name change request. You should process this message in case the server gave you a different name than you requested. Finally, once you have a name, you can join a channel with 2.1.0.2 JoinChannel. The flags you specify here will be used if the channel doesn't exist yet (e.g. nobody is in the chat yet) - these should match the ones in the MMF2 project file. The name should also match.
After all that, you're still not done! You have to process more messages, etc. it's almost like writing the RelayClient class yourself. It's a tough task, but with the protocol specification in hand you should be able to work it all out.

UDP socket and multiple replies

I'm a learner, so please be patient and clear. I am writing an echo client with Java sockets (DatagramSocket).
After the client sends a message to the echo server, the server deliberately sends 1-10 copies of the message back to simulate message duplication in UDP.
However, my code can only receive the first of those messages sent back, never the full number sent by the server. My receive code is like this:
socket.receive(receivePacket);
How would I put my client in a state where you can enter a string to echo, say "Hi", it is then sent to the server, but can then receive all the replies? I am assuming that they all make it back to the client (I am testing this on my local machine so there will be no loss)
Call socket.receive again to receive additional packets. Set a timeout to wait a reasonable amount of time before deciding the server has sent all its packets.

Categories