Chat using TCP in Java - java

I am making a chat in Java which uses a TCP protocol.
I have a client and a server side.
To send a message to another user, I have to send the message to the server through my client, and the server has to send it to another client.
The server holds the addresses of both online users. When I send a private message, the server finds the ip and a port and creates a socket from them.
The problem is that it doesn’t work correctly.
Here’s the code:
int portNumber = 4444;
String host = "192.168.0.100”;
Socket link;
try {
link = new Socket(host, portNumber);
// Then I set to already created PrintWriter the outputstream
out = new PrintWriter(link.getOutputStream(), true);
} catch (Exception e) {}
// Unfortunately the server freezes here (it doesn't show anything).
How to solve this problem? Where dod I make a mistake?
Thank you in advance.

You shouldn't create a new Socket to send a message. Instead, use a socket of an existing connection.
The sequence should be the following:
Client A connects to the server (server stores the connection as SocketA).
Client B connects to the server (server stores the connection as SocketB).
Server reads a private message from SocketA. The message is addressed to client B.
Server finds the existing socket for client B. It's SocketB.
Server sends the message into SocketB.

Related

There is Option to read data from socket without the server close the socket?

I created application in android studio and server in python and I want to connect the client to my server with one socket per client so that I don't need to close the socket and I could send data from the server to any connected client I want.
My server is multi-threaded and it working only if I'm closing every socket after sending data back.
At my java app I created class that contain socket object and methods to contact with the server and I think that my problem is at this method:
private static String getMessageFromServer() throws IOException {
in = new InputStreamReader(sock.getInputStream());
bf = new BufferedReader(in);
return bf.readLine();
}
As you can see this method reads data from the server and the problem is that it keep reading data until the server close the socket, so I'm asking if there is any option to read data from server and stop the reading after I already got the data and without the server closes the socket?
Thanks :-)

Java sockets: Client get IP-adress and port to connect to server

I'm stuck at a homework assignment for my university course.
We are supposed to write a game of Rock-Paper-Scissors using Client and Server, choosing TCP or UDP.
The assignment for the client part is:
"Get the IP-address and port of the server at the beginning and than use this information to connect to the server."
And server:
"The port needs to be set to a number between 10000 and 20000 at the start using command line input."
Now this got me wondering. How is the Client supposed to get the Ip-Adress and port of the server if it is not connected to the server yet?
And normally the client and the server creates a socket and the server listens if a client wants to connect and then accepts the request, making a connection, not the client, like it is requested in the assignment. Isn't it impossible to know the server, if not connected yet?
I got a version working, if the server goes:
// Setting the port via console, making an output: "please enter valid port" and returns the entered port number
ServerTest.port = ServerTest.getPort();
...
ServerSocket testSocket = new ServerSocket(ServerTest.port);
and the client:
private static String host = "localhost";
private static Integer port = 1337;
...
Socket clientSocket = new Socket(ClientTest.host, ClientTest.port);
if I set the port to 1337 when starting the server.
Then I tried something like
//Client
port = ServerTest.getServerPort();
...
Socket clientSocket = new Socket(ClientTest.host, ClientTest.port);
and in the server-class:
public static Integer getServerPort(){
return port;
}
But that throws an "Connection refused"-exception, even if I first the server at first, set the port and than start the client.
Does anyone have an idea how to solve this?

How do I make a client-server Java application to send messages on one port but receive them on another?

I am currently trying to make an application that will send messages to a server using one port, but will receive messages on another port. However, based on tutorials I have followed, it looks like the act of connecting to the server is where ports come into play and my client is receiving and sending messages on the same port. How do I make it so it sends on one port but receives on the other?
Here is the code that I think is relevant from the client side (I put some stuff that seems unrelated because I think they are things that would be altered by receiving on one port but sending on another, and ignore the comment about replacing inetaddress, that is just me working on implementing this in a gui):
public void startRunning(){
try{
connectToServer();
setupStreams();
whileChatting();
}catch(EOFException eofException){
showMessage("\n Client terminated connection");
}catch(IOException ioException){
ioException.printStackTrace();
}finally{
closeStuff();
}
}
//connect to server
private void connectToServer() throws IOException{
showMessage("Attempting connection... \n");
connection = new Socket(InetAddress.getByName(serverIP), 480);//replace serverIP with ipTextField.getText or set serverIP to equal ipTextField.getText? Same with port number.
showMessage("Connected to: " + connection.getInetAddress().getHostName() );
}
//set up streams to send and receive messages
private void setupStreams() throws IOException{
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());
showMessage("\n Streams are good! \n");
}
//while talking with server
private void whileChatting() throws IOException{
ableToType(true);
do{
try{
message = (String) input.readObject();
showMessage("\n" + message);
}catch(ClassNotFoundException classNotfoundException){
showMessage("\n Don't know that object type");
}
}while(!message.equals("SERVER - END"));
}
//send messages to server
private void sendMessage(String message){
try{
output.writeObject("CLIENT - " + message);
output.flush();
showMessage("\nCLIENT - " + message);
}catch(IOException ioException){
messageWindow.append("\n something messed up ");
}
}
//change/update message window
private void showMessage(final String m){
SwingUtilities.invokeLater(
new Runnable(){
public void run(){
messageWindow.append(m);
}
}
);
}
EDIT/UPDATE: To help clarify some things, here is some more information. The device that sends the first message is connected to a sensor, and it sends information when that sensor detects something to the other device. The receiving device sends a message back on a different port telling the original sending device how to respond. Lets name these two devices the "reporter-action taker" and the "decision maker-commander".
If you want to use TCP/IP sockets you can't use a a socket to send and another to read. That's not what they are for.
If you use a centralized distributed algorithm (server/client communication) you have to set the server to listen on a single socket port with the ServerSocket class: then the server tries to accept clients through that socket.
Example:
ServerSocket listener = new ServerSocket(Port)
While (true) {
new Clienthandler(listener.accept());
}
The server will listen on that port, and when a client tries to connect to that port if it is accepted the server launches its handler. On this handler constructor the Socket object used on the client is received on an argument and can then be used to get the writers and the readers. The reader on this handler class will be the writer on the client class and vice-versa, maybe that's what you were looking for.
Your question about using two ports in this manner is a bit strange. You state that you have a client and a server and that they should communicate on different ports.
Just to clarify picture the server as a hanging rack for jackets with several hooks in a row. Each port the server listened on represents a hook. When it comes to the client server relationship the client or jacket knows where to find its hook, however the hook is blind and have no idea where to find jackets.
Now, the client selects a port or a hook and connects to it. The connection is like a pipeline with two pipes. One for the client to deliver data to the server with and the other to send data from the server back to the client. When the connection is established data can be transferred both ways. This means that we only need one port open on the server to send data both from the client to the server and in the opposite direction.
The reason for only having one open port open on the server for the clients to connect to is that holding an open port for connections is hard to do on a regular client computer. The normal desktop user will be behind several firewalls blocking incoming connections. If that wasn't the case the client would probably be hacked senseless from malicious viruses.
Moving on with the two port solution we could not call this a client server connection per say. It would be more like a peer to peer connection or something like that. But if this is what you want to do, the application connecting first would have to start by telling the other application what ip and port to use for connecting back, it should probably also want to give some kind of token that are to be used to pair the new incoming connection when connecting back.
You should take note that making such an implementation is not a good idea most of the time as it complicates things a whole lot for simple data transfer between a client and server application.

Socket programming client name

Is there any way to get client name at the server side before "accepting" the connection? Using java.
I am new to java.
thanks in advance..
Is there any way to get client name at the server side before "accepting" the connection?
No - you must accept the connection first. Then you may read the host's name and choose the next course of action.
Socket client = server.accept();
String hostName = client.getInetAddress().getHostName();
The client name (the client hostname) is avalaible only from the Socket client, so you need to accept it first and then then to react accordingly.
private static final String ALLOWED_NAME = "my.hostname.com";
....
Socket client = server.accept();
String hostName = client.getInetAddress().getCanonicalHostName();
if(hostName.equalsIgnoreCase(ALLOWED_NAME)
{
// DO NOTHING
}
else
{
client.close();
}
Reference:
Socket
InetAddress
Please be sure to get the difference between getCanonicalHostname() and getHostname().

Communiation with multiple clients via Sockets

I have a Server Socket and 3-4 android devices as clients. I'm using TCP/IP for communications. Which is the best method. Should I use multiple ports for each client? Or should I use same port. If using same function then how should I identify the communication addressed to different devices?
No, you do not need several ports.
ServerSocket server = new ServerSocket(port);
while (true)
{
Socket socket = server.accept();
// do something with this socket - aka 1 client
new SomeClientClass(socket);
InputStream in = socket.getInputStream();
in.read(byte[]);
OutputStream out = socket.getOutputStream;
// out will only write response to its own client.
// when this new SomeClientClassis created, method returns to this point
// in while loop and waits for the next client
}
You can use one port. The client can send you its id. If it can't you can look at the clients IP address to workout which one it is.
There are thousands of TCP client/server code examples on the web, but I would start with the sample code which comes with the JDK,

Categories

Resources