Java socket - client and server IP address - java

I am writing a program with TCP sockets connection between client and server. When the server starts I want to display the IP and port that clients need to use to connect, and when client connects I want the server to show what IP did the client connect from. I am getting confused which command should i use to each of those:
getInetAdress()
getLocalAdress()
getRemoteSocketAdress()
edit
I earlier used int port = 1234 and String IP = "localhost" to test and it worked, but I only used it on one PC, so I think localhost will not work if i start server and client on different computers.
This is server side:
int port = 1234;
...
public void start() {
keepRunning = true;
// create socket
try {
ServerSocket server = new ServerSocket(port);
while (keepRunning) {
display("Waiting for client connections on "
+ server.getInetAddress().getLocalHost()
.getHostAddress() + ":" + port);
Socket conn = server.accept();
if (!keepRunning)
break;
ClientThread t = new ClientThread(conn);
cList.add(t);
t.start();
And this is client:
int port = 1234;
String IP = "localhost";
//these variables can be changed from Client GUI before making connection
...
public boolean start() {
try {
socket = new Socket(IP, port);
} catch (Exception e) {
display("Error connectiong to server:" + e);
return false;
}
try {
sInput = new ObjectInputStream(socket.getInputStream());
sOutput = new ObjectOutputStream(socket.getOutputStream());
} catch (IOException e) {
display("Exception creating new Input/output Streams: " + e);
return false;
}
When i start the server,
display("Waiting for client connections on " + server.getInetAddress().getLocalHost().getHostAddress() + ":" + port);
return this:
Waiting for client connections on 192.168.1.104:1234
which is kind of what i want, but I still cant get it to show me the port. 1234 is a fixed value i used, but I want to use ServerSocket server = new ServerSocket(0); to asign port dynamically, then when i start the client i just put in the values that i got from server and connect.
I tried to use server.getLocalPort() in the display line in server and it returned 55410 or something like that, but when i put this port in client to make connection, it doesn't work. I get Error connectiong to server:java.net.ConnectException: Connection refused: connect. from client

To get the current port that the ServerSocket is listening to, use getLocalPort();
http://download.java.net/jdk7/archive/b123/docs/api/java/net/ServerSocket.html#getLocalPort%28%29
getLocalPort
public int getLocalPort()
Returns the port number on which this socket is listening.
If the socket was bound prior to being closed, then this method will continue to return the port number after the socket is closed.
Edit: Just saw your edit. Are you trying to connect by explicitly referencing the IP and Port? If so, and it's still failing, your server machine might be running a firewall. I'd check for that first.

Related

resource leak : serversocket is never closed when using while loop for getting client requests

I tried to find in exact solution for this problem but I'm not able to find it
I have written a while loop to accept client sockets in server program
because of this I'm unable to close the serversocket as it is always listening
here is my server code
public class nserver {
public static void main(String[] args) throws IOException {
int port=4413;
//server is running on port
try(ServerSocket ss = new ServerSocket(port)){;
// socket accepts data from the incoming clients
while(true){
Socket socket = ss.accept();
// id I don't put the if case then this loop never breaks and
// although I wrote ss.close() - it will never reached - so use if case
if(socket.equals(null))
break;
System.out.println("Server is running on port "+port);
//socket.getInetAddress gives address of client ip not the server ip as the socket is mada as client socket
System.out.println("server recieved connection from "+socket.getInetAddress()+" : "+socket.getPort());
//create two threads to send and receive from client
rxClientData rx = new rxClientData(socket);
Thread t = new Thread(rx);
t.start();
sdServerData sd = new sdServerData(socket);
Thread t2 = new Thread(sd);
t2.start();
// if I put ss.close() here then it will accept only one client socket and serversocket will be closed after this line
}
ss.close();
}
catch(Exception e){
System.out.println(e.getMessage());
}
}
}
how to close serversocket after my client socket requests,I have 3 clients
with for loop I will have a limit of no.of client sockets,but a server should accept so many no.of requests - so I used while loop
for a server do we need to keep serversocket open in real world scenario ? - so that it accepts client requests all the time

Java server socket response to previouse connected client [duplicate]

I'm trying to implement a TCP connection, everything works fine from the server's side but when I run the client program (from client computer) I get the following error:
java.net.ConnectException: Connection refused
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:432)
at java.net.Socket.connect(Socket.java:529)
at java.net.Socket.connect(Socket.java:478)
at java.net.Socket.<init>(Socket.java:375)
at java.net.Socket.<init>(Socket.java:189)
at TCPClient.main(TCPClient.java:13)
I tried changing the socket number in case it was in use but to no avail, does anyone know what is causing this error & how to fix it.
The Server Code:
//TCPServer.java
import java.io.*;
import java.net.*;
class TCPServer {
public static void main(String argv[]) throws Exception {
String fromclient;
String toclient;
ServerSocket Server = new ServerSocket(5000);
System.out.println("TCPServer Waiting for client on port 5000");
while (true) {
Socket connected = Server.accept();
System.out.println(" THE CLIENT" + " " + connected.getInetAddress()
+ ":" + connected.getPort() + " IS CONNECTED ");
BufferedReader inFromUser = new BufferedReader(
new InputStreamReader(System.in));
BufferedReader inFromClient = new BufferedReader(
new InputStreamReader(connected.getInputStream()));
PrintWriter outToClient = new PrintWriter(
connected.getOutputStream(), true);
while (true) {
System.out.println("SEND(Type Q or q to Quit):");
toclient = inFromUser.readLine();
if (toclient.equals("q") || toclient.equals("Q")) {
outToClient.println(toclient);
connected.close();
break;
} else {
outToClient.println(toclient);
}
fromclient = inFromClient.readLine();
if (fromclient.equals("q") || fromclient.equals("Q")) {
connected.close();
break;
} else {
System.out.println("RECIEVED:" + fromclient);
}
}
}
}
}
The Client Code:
//TCPClient.java
import java.io.*;
import java.net.*;
class TCPClient {
public static void main(String argv[]) throws Exception {
String FromServer;
String ToServer;
Socket clientSocket = new Socket("localhost", 5000);
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(
System.in));
PrintWriter outToServer = new PrintWriter(
clientSocket.getOutputStream(), true);
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
while (true) {
FromServer = inFromServer.readLine();
if (FromServer.equals("q") || FromServer.equals("Q")) {
clientSocket.close();
break;
} else {
System.out.println("RECIEVED:" + FromServer);
System.out.println("SEND(Type Q or q to Quit):");
ToServer = inFromUser.readLine();
if (ToServer.equals("Q") || ToServer.equals("q")) {
outToServer.println(ToServer);
clientSocket.close();
break;
} else {
outToServer.println(ToServer);
}
}
}
}
}
This exception means that there is no service listening on the IP/port you are trying to connect to:
You are trying to connect to the wrong IP/Host or port.
You have not started your server.
Your server is not listening for connections.
On Windows servers, the listen backlog queue is full.
I would check:
Host name and port you're trying to connect to
The server side has managed to start listening correctly
There's no firewall blocking the connection
The simplest starting point is probably to try to connect manually from the client machine using telnet or Putty. If that succeeds, then the problem is in your client code. If it doesn't, you need to work out why it hasn't. Wireshark may help you on this front.
You have to connect your client socket to the remote ServerSocket. Instead of
Socket clientSocket = new Socket("localhost", 5000);
do
Socket clientSocket = new Socket(serverName, 5000);
The client must connect to serverName which should match the name or IP of the box on which your ServerSocket was instantiated (the name must be reachable from the client machine). BTW: It's not the name that is important, it's all about IP addresses...
I had the same problem, but running the Server before running the Client fixed it.
One point that I would like to add to the answers above is my experience-
"I hosted on my server on localhost and was trying to connect to it through an android emulator by specifying proper URL like http://localhost/my_api/login.php . And I was getting connection refused error"
Point to note - When I just went to browser on the PC and use the same URL (http://localhost/my_api/login.php) I was getting correct response
so the Problem in my case was the term localhost which I replaced with the IP for my server (as your server is hosted on your machine) which made it reachable from my emulator on the same PC.
To get IP for your local machine, you can use ipconfig command on cmd
you will get IPv4 something like 192.68.xx.yy
Voila ..that's your machine's IP where you have your server hosted.
use it then instead of localhost
http://192.168.72.66/my_api/login.php
Note - you won't be able to reach this private IP from any node outside this computer. (In case you need ,you can use Ngnix for that)
I had the same problem with Mqtt broker called vernemq.but solved it by adding the following.
$ sudo vmq-admin listener show
to show the list o allowed ips and ports for vernemq
$ sudo vmq-admin listener start port=1885 -a 0.0.0.0 --mountpoint /appname --nr_of_acceptors=10 --max_connections=20000
to add any ip and your new port. now u should be able to connect without any problem.
Hope it solves your problem.
Hope my experience may be useful to someone. I faced the problem with the same exception stack trace and I couldn't understand what the issue was. The Database server which I was trying to connect was running and the port was open and was accepting connections.
The issue was with internet connection. The internet connection that I was using was not allowed to connect to the corresponding server. When I changed the connection details, the issue got resolved.
In my case, I gave the socket the name of the server (in my case "raspberrypi"), and instead an IPv4 address made it, or to specify, IPv6 was broken (the name resolved to an IPv6)
In my case, I had to put a check mark near Expose daemon on tcp://localhost:2375 without TLS in docker setting (on the right side of the task bar, right click on docker, select setting)
i got this error because I closed ServerSocket inside a for loop that try to accept number of clients inside it (I did not finished accepting all clints)
so be careful where to close your Socket
I had same problem and the problem was that I was not closing socket object.After using socket.close(); problem solved.
This code works for me.
ClientDemo.java
public class ClientDemo {
public static void main(String[] args) throws UnknownHostException,
IOException {
Socket socket = new Socket("127.0.0.1", 55286);
OutputStreamWriter os = new OutputStreamWriter(socket.getOutputStream());
os.write("Santosh Karna");
os.flush();
socket.close();
}
}
and
ServerDemo.java
public class ServerDemo {
public static void main(String[] args) throws IOException {
System.out.println("server is started");
ServerSocket serverSocket= new ServerSocket(55286);
System.out.println("server is waiting");
Socket socket=serverSocket.accept();
System.out.println("Client connected");
BufferedReader reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
String str=reader.readLine();
System.out.println("Client data: "+str);
socket.close();
serverSocket.close();
}
}
I changed my DNS network and it fixed the problem
You probably didn't initialize the server or client is trying to connect to wrong ip/port.
Change local host to your ip address
localhost
//to you local ip
192.168.xxxx
I saw the same error message ""java.net.ConnectException: Connection refused" in SQuirreLSQL when it was trying to connect to a postgresql database through an ssh tunnel.
Example of opening tunel:
Example of error in Squirrel with Postgresql:
It was trying to connect to the wrong port. After entering the correct port, the process execution was successful.
See more options to fix this error at: https://stackoverflow.com/a/6876306/5857023
In my case, with server written in c# and client written in Java, I resolved it by specifying hostname as 'localhost' in the server, and '[::1]' in the client. I don't know why that is, but specifying 'localhost' in the client did not work.
Supposedly these are synonyms in many ways, but apparently, not not a 100% match. Hope it helps someone avoid a headache.
For those who are experiencing the same problem and use Spring framework, I would suggest to check an http connection provider configuration. I mean RestTemplate, WebClient, etc.
In my case there was a problem with configured RestTemplate (it's just an example):
public RestTemplate localRestTemplate() {
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", <some port>));
SimpleClientHttpRequestFactory clientHttpReq = new SimpleClientHttpRequestFactory();
clientHttpReq.setProxy(proxy);
return new RestTemplate(clientHttpReq);
}
I just simplified configuration to:
public RestTemplate restTemplate() {
return new RestTemplate(new SimpleClientHttpRequestFactory());
}
And it started to work properly.
There is a service called MySQL80 that should be running to connect to the database
for windows you can access it by searching for services than look for MySQL80 service and make sure it is running
It could be that there is a previous instance of the client still running and listening on port 5000.

Java Broadcasting: throw BindException

I want that my client application is able to connect to a Server application.
The problem is that my Client doesn't know the Server ip (in LAN).
So I tried to use java object MulticastSocket. Luckily Oracle have a page with an example of Broadcasting.
Here I have rearranged it for my use.
Server code:
long FIVE_SECONDS = 5000;
int port = 4445;
DatagramSocket socket = new DatagramSocket(port);
while (true) {
System.out.println("Server running...");
try {
// message for client
String dString = "Hello Client";
byte[] buf = dString.getBytes();
// send
InetAddress group = InetAddress.getByName("230.0.0.1");
DatagramPacket packet = new DatagramPacket(buf, buf.length, group, port);
socket.send(packet);
// sleep for a while
try {
Thread.sleep((long)(Math.random() * FIVE_SECONDS));
}
catch (InterruptedException e) {
System.err.println("Interrupted Exception");
}
} catch (IOException e) {
System.err.println("IOException");
}
}
Client code:
MulticastSocket socket = new MulticastSocket(4445);
InetAddress address = InetAddress.getByName("230.0.0.1");
socket.joinGroup(address);
// receive the message
byte[] buf = new byte[256];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
String received = new String(packet.getData(), 0, packet.getLength());
System.out.println("Received: " + received);
socket.leaveGroup(address);
socket.close();
When I run Srver: no problem, but when I try running client it throw java.net.BindException: Address already in use cause both client and server are listening/sending information on port 4445.
But isn't it right? To connect each other they must have the same port number, or they'll never 'meet'.
Can I solve this problem? How?
Are the port number correct?
Is this a right resolution to the problem about the unknown server ip?
Thanks!
As Warren mentioned in his answer, your client and server can't bind to the same port on the same machine. The Oracle example is not doing that.
The client should bind to port 4446 and the server should bind to port 4445. When the server create a DatagramPacket it should do so with the client's port which is 4446.
If you do this and the client still can't receive, you may need to set the outgoing interface for multicast on the server. You can do this with either the setInterface or setNetworkInterface methods.
For example, suppose your serverhas IP addresses 192.168.1.1 and 192.168.2.1. If you want your sender to send from 192.168.1.1, you would call:
multicastSocket.setInterface(InetAddress.getByName("192.168.1.1"));
You are getting this exception because you are trying to run your server application and your client application on the same machine. When you start your client, your server has already bound to port 4445, so it is already in use - and thus unavailable - when your client tries to bind to it.
Running your server and your client on different machines would get around that particular error. However, you could also get around it by choosing different ports for your server and your client.
For example if you ran your server on port 4445, and your client on port 4446, you could do the following. On the server, you would add a variable for the client port, and use the client port as the destination port when sending your DatagramPacket:
int clientPort = 4446;
...
DatagramPacket packet = new DatagramPacket(buf, buf.length, group, clientPort);
instead of
DatagramPacket packet = new DatagramPacket(buf, buf.length, group, port);
On the client, you would simply bind to the client port instead of the server port:
MulticastSocket socket = new MulticastSocket(4446);
instead of
MulticastSocket socket = new MulticastSocket(4445);
Using different port numbers for the server and for the client would allow you to run both the server application and the client application on the same machine and get you past this particular issue.

Java socket hanging when inside of java servlet

So I've been trying to figure out how to send messages between my arduino and my java servlet (tomcat) and have been bumping into some problems. I'm using this code in my java servlet:
ServerSocket server;
//socket server port on which it will listen
int port = 9876;
String message = "";
//create the socket server object
server = new ServerSocket(port);
System.out.println("Server socket created");
//keep listens indefinitely until receives 'exit' call or program terminates
while(true){
System.out.println("Waiting for client request...");
//creating socket and waiting for client connection
Socket socket = server.accept();
BufferedReader buff = new BufferedReader(new InputStreamReader (socket.getInputStream()));
System.out.println("Input stream established");
message = buff.readLine();
System.out.println("Message Received: " + message);
buff.close();
socket.close();
//terminate the server if client sends exit request
if(message.equalsIgnoreCase("exit")) break;
}
System.out.println("Shutting down Socket server!!");
//close the ServerSocket object
server.close();
But it's hanging on the
Socket socket = server.accept();
line. I assume this is because the messages i'm sending from the arduino aren't arriving. On the arduino side of things, this is my client:
if (client.connect(ip, 9876)) {
Serial.println("connected");
client.println("12345678");
Serial.println("Message sent");
} else {
Serial.println("connection failed");
}
Not much to it. Now, I've tried sending this as a HTTP POST request, but without success (surely i'm doing it incorrectly, i just don't know how to do it, i've tried for a while). I know this is probably horrifically written, but i'm very open to learning from you guys today.
The weird thing is that this works exactly how i want it to when i put the java server code in a new regular java project. Can anyone help me figure this out? Why is it hanging in the servlet but not in a regular java project?

What name do i use to connect to a server socket in java

I am writing a telnet like program in java using the server socket and socket classes. This is my current code for the client program. The user types in the server name and the port they would like to connect on.
static Socket getSocket()
{
while(true)
{
System.out.println("What server do you want to connect to on which port?");
String info = sc.nextLine();
String host = info.split(" ")[0];
int port = Integer.parseInt(info.split(" ")[1]);
try
{
InetAddress ip = InetAddress.getByName(host);
return new Socket(ip, port);
}
catch (UnknownHostException e)
{
System.err.println("The host is unknown.");
}
catch (IOException e)
{
System.err.println("Network error.");
}
}
}
I tried connecting on localhost, and it worked. Then i tried connecting with my friend on a remote computer using the ip address as the network name and it did not work giving an exception. What name do i use to connect to a remote server.
You need to give your friend your remote IP address.

Categories