I am creating a simple learning project (chat using sockets) in Java and today I faced a problem. Maybe the point is an obvious one for somebody, but I am confused with it
The purpose
To get to know (at least one of the following):
A list of the currently opened free/taken ports on a PC
Whether the port I want to use is locked
What I tried
I've created a simple raw-project and run two ServerSocket on one port. In this case I have caught a java.net.BindException with notification that "...Address already in use: JVM_Bind...". But in this way I am able to check the port avaliability only if my JVM has captured it. In case if other program listens to the port, I do not know anything about it. I am adding a code below.
public class Main {
public static void main(String[] args) throws IOException {
MyThread myThread = new MyThread();
ServerSocket serverSocket = new ServerSocket(5940);
myThread.start();
serverSocket.accept();
}
}
public class MyThread extends Thread {
#Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(5940);// exception is thrown here
serverSocket.accept();
} catch (IOException e) {
System.err.println("SECOND SERVER");
e.printStackTrace();
interrupt();
}
}
}
PS Any advice is warmly welcomed
I've created a simple raw-project and run two ServerSocket on one
port. In this case I have caught a java.net.BindException with
notification that "...Address already in use: JVM_Bind...". But in
this way I am able to check the port avaliability only if my JVM has
captured it. In case if other program listens to the port, I do not
know anything about it.
I think you're misinterpreting your result. I have every reason to believe that if the port you request is already bound by any process then your attempt to bind it will fail with a BindException. That takes care of
Whether the port I want to use is locked
. As for
A list of the currently opened free/taken ports on a PC
, there are system utilities that can get you that information, but it is useless to you. Whichever end initiates the connection (i.e. the client) needs to know in advance what port to try to connect to. It cannot get that from the server, because that presents a chicken & egg problem.
The usual approach is that the server listens to a specific port chosen by its developer or its admin, and that port number is provided to clients out of band -- often simply by it being a standard, well-known port number. That's how most of the basic network protocols work; for example, HTTP servers run on port 80 by default. If the wanted port happens to be unavailable when the server attempts to bind to it then that indicates a misconfiguration of the machine, and the server simply fails to start.
The client, on the other hand, does not need to choose a port number at all. The system will choose one for it automatically when it attempts to connect to the server.
Related
This question already has answers here:
Java socket API: How to tell if a connection has been closed?
(9 answers)
Closed 2 years ago.
So I'm in the making of a very simple server/client complex using java. So far I have managed to figure out what happens if the client quits, because then the server receives null while listening from any input from the client.
BUT - what happens if the client is connected and the server quits for any reason... the server is supposed to wait for input from the client, but how can the client know that the server is not listening anymore? For me the clients call to the server just goes into the void... nothing happens...
Can I do something to find out when the server goes down? Time-out, ping/pong or something?
As You surely can see I'm quite new at this, I'm just curious. This was a puzzle for me ever since I attended computer science at the university.
Thanks in advance. dr_xemacs.
(I am assuming you are working with blocking server socket and socket and not with non blocking ones)
Similarly to the server, reading from streams of a closed connection will return null.
However if you instead do not want to rely on this or a scared that the connection to the server could somehow persist, you can also use time outs (check this out! ) which will throw SocketTimeoutException when the time is up and, to keep track of whether the server is up or not, create a ping/packet to assure server is still up and running.
Edit: I did a quick search and this could be useful to you! Take a look!
How can the client know that the server is not listening anymore?
If the client doesn't attempt to interact at some level with the service, it won't know.
Assuming that the client has sent a request, a few different scenarios.
If the service is no longer listening on the designated port, the client will typically get a "Connection Refused" exception.
If the service is still running (in a sense) but it is not working properly, then connection attempts from the client are likely to time out.
If the service's host is down, the client liable get a timeout.
If there are network connectivity or firewall issues, the client could get a timeout or some other exception.
Can I do something to find out when the server goes down? Time-out, ping/pong or something?
You attempt to connect and send a request. If it fails or times out, that means the service is down. If you are designing and implementing the service yourself, you could include a special "healthcheck" request for clients to "ping" on. But the flip-side is that network and server resources will be consumed in receiving and responding to these requests. It can affect your ability to scale up the number of clients, for example, if each client pings the service every N seconds.
But a client typically doesn't need to know whether the service is up or down. It typically only cares that service responds when it it sends a real request. And the simplest way to handle that is to just send the request and deal with the outcome. (The client code has to deal with all possible outcomes anyway when doing a real request. The service can go down, etc between the last healthcheck ping and when the client sends a real request.)
Bottom line: Don't bother with checking availability in the client unless the application (i.e. the end user) really needs to know.
Your Server probably may be running on a certain port and so you can add a health check at the client side and update a global flag with status to let client know about its availibity :-
Socket socket = null;
try
{
socket = new Socket(host, port);
return true;
}
catch (Exception e)
{
return false;
}
finally
{
if(socket != null)
try
{
socket.close();
}
catch(Exception e){}
}
I'm trying to create a multi-client/server application in Java. I'm having quite some issues because my threads seem to get entangled... Here's what I'm trying to do.
I have a Server-class that accepts clients by using this piece of code:
while(true){
Socket socket = serverSocket.accept();
}
My server should remember the clients that are connected so I create a new Thread called ClientThread with that socket and place that Thread in a List on the Server
That Thread listens to Command-objects that are sent from the client. If it receives a Command, it needs to send it to the Server instance for further processing (without creating a new instance of Server on that ClientThread). I've tried to do this by adding the Server-instance to this Thread when it's created. (Is this the right way?)
My Server should also be able to send Objects back to the clients (1 or more) at any time. I'm trying to do this by using socket.getOutputStream() that is kept in the ClientThread
How should I organize my Threads so that every client is constantly listening to accept objects from the server AND that they can send objects to the Server at any time.
I know this isn't really a specific question, but if you know some info or tutorials that might be helpful for this use case, I'd be really thankful.
btw: I know how to create sockets and send (serializable) objects and so on.. I'm just stuck on how to organize everything
You appear to have tangled Thread and objects. I would
a) make sure you are not extending Thread anywhere or calling your objects XxxxThread. Using an ExecutorService to manage your threads is a good idea.
b) have a simple model for responding to client commands, e.g. each client thread reads a task and then performs a task.
c) Have a wrapper for each connections, e.g. with a sendMessage method.
Since you already know about sockets and threads, I send you the idea pseudo code (case need a specific part of code just let me know)
One thing you did not mention is how to keep track of clients, by its IP o by any other method like an ID? Can any given device open more than one connection with different client ID? Or you'll only accept one connection per device? In any case, if a client is already in the list, what do you suposse to do? Will you communicate the created thread the new socket? Will you destroy that thread and create a new one? Or maybe you'll ignore this new request?
This is my idea (taken from a working application):
Server prepares the server socket and wait in the accept state.
Once a client connects, the server start a thread to attend the client passing the socket it just created with the accept command. When the thread which attends the client starts, the very first message it receives from the client should be a password o special signature to let the client gets in (this is optional).
Server code:
Prepares the server socket which listen in a well known port
Clear client list;
While (!Terminated)
{
// if you want to impose a limit for connections, check it here:
if (Is the list of connected client full?)
{
Sleep(reasonable time in seconds or miliseconds);
continue;
}
ClientSocket = ServerSocket.Accept();
if the client's IP is already in the list
{
depends on what you want to do.
}
else
{
Add client's IP to the list
Start (create) new client Tread(ClientSocket);
}
}
// when server finish
If (client list is not empty?)
{
Kill all threads
or
Wait until all threads are done
or
Wait an amount of time and then kill those remaining.
}
thread client code:
// This is optional, just to make sure a valid client is connected
Read packet from ClientSocket
if (!Is_the_passport_packet)
{
close socket;
return;
}
// if passport is not required, start here
Try
{
While (!Terminated)
{
if (read packet from client);
{
switch (packet.Command)
{
// In your question you said you want the Server thread to process the request
// I guess you have your requirements to do so,
// anyway, you must use a mutex o some other synchronization method.
case TASK_1:
[sync] process TASK_1(packet, ClientSocket);
break;
case TASK_2:
[sync] process TASK_2(packet, ClientSocket);
break;
etc ….
case WORK_DONE:
Close Socket;
return;
default:
Log(received an unknown command: packet.command);
break;
}
}
else if (Client has quit (closed/broken socket))
{
// as you may know, a socket is consider shutdown when you received a 0 length data
// and a broken connection when received -1 in either case all you have to do is
Close Socket;
return;
}
}
}
catch (Exception e)
{
Log(received an exception: e.message);
}
finally
{
Remove this client from the client's list
}
Background: I'm writing a simple UDP application to ping a beta server I manage every minute or so to tell me it is still up and running (I can't enable ping on the server for those that are wondering). I plan to run this on my phone to warn me when the server is no longer responding.
I'm trying to use the seemingly simple java.net.DatagramSocket as such:
try
{
socket = new DatagramSocket();
socket.bind(null);
}
catch (SocketException e)
{
System.out.println(e.toString());
throw e;
}
Let me also say that I have enabled the Internet permissions through the android manifest and if I remove the uses clause to do so, I get a permissions error so I'm sure that is working OK. When I download this code to an Android Virtual Device (AVD) and execute it, on the call to bind() I am presented with this exception:
03-17 19:07:39.401: INFO/System.out(338): java.net.BindException: Invalid argument
According to this documentation, the null argument is correct:
public void bind (SocketAddress localAddr)
Since: API Level 1
Binds this socket to the local address and port specified by localAddr. If this value is null any free port on a valid local address is used.
But not trusting documentation, I decided to enumerate the IP addresses on my device like this:
ArrayList<NetworkInterface> allInterfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
NetworkInterface eth = allInterfaces.get(0);
InetSocketAddress addr = new InetSocketAddress(eth.getInetAddresses().nextElement(), port);
try
{
socket = new DatagramSocket();
socket.bind(addr);
}
catch (SocketException e)
{
System.out.println(e.toString());
throw e;
}
When I step through the code, it works great and I can see the two IP address on the AVD but I get the exact same exception on the bind() call. Does anybody out there see what i might be missing? I will continue to research and hopefully post a solution to my own problem, but I am hoping somebody out there will be able to shortcut this for me.
[Edited: if you saw my previous response I made the classic debugging mistake of changing two variable in one test and it was the other one that solved my problem.]
I found the problem. It is the way I'm declaring the DatagramSocket that appears to cause problems. If I use a DatagramChannel to open the DatagramSocket in the following way then the bind() call is successful.
DatagramChannel channel = DatagramChannel.open();
DatagramSocket socket = channel.socket();
I've stumbled across this problem either and have found the cause: if you call the parameterless constructor new DatagramSocket(), this creates "a UDP datagram socket which is bound to any available port on the local host using a wildcard address" (as per the API docs). So this actually means, the Socket is already bound. My "fix" for this is as follows:
SocketAddress socketAddress = new SocketAddress(yourInetAddress, yourPort);
DatagramSocket serverSocket = new DatagramSocket(null);
serverSocket.bind(socketAddress);
This explicitly creates an unbound Socket (through the DatagramSocket (SocketAddress localAddr) constructor), making it possible to bind the Socket in turn.
This is probably the more elegant solution than creating an unnecessary channel.
P.S.: Strangely enough, this is where DatagramSocket differs from a TCP ServerSocket: the parameterless constructor of the latter will create an unbound ServerSocket, not triggering this problem.
I am trying to figure out how to create a java program that can listen to multiple ports and perform different actions depending on which port the client speaks to.
I've seen and understand the basic client-server program:
http://systembash.com/content/a-simple-java-tcp-server-and-tcp-client/
Just to reiterate, I want to create this same relationship, but instead of the server only listening on one port and performing one action when it receives input, I want it to listen on multiple ports and depending which port the client connects and sends data to, perform a different action.
I'm hoping to make each port accept a GET and PUT command in the future, but for now I'm just trying to figure out how to set up the basic structure of the server which will be able to listen to multiple ports. I've tried googling, but I can't seem to find much, so any help is appreciated.
Thanks in advance.
-Anthony
The tutorial you've mentioned is very basic. You cannot write any reasonable server without using threads. In order to have two server sockets, you must spawn a new thread for each port, like this (pseudocode):
new Thread() {
public void run() {
ServerSocket server = new ServerSocket(6788);
while(true) {
Socket client1 = server.accept();
//handle client1
}
}.start();
and (notice the different port):
new Thread() {
public void run() {
ServerSocket server = new ServerSocket(6789);
while(true) {
Socket client1 = server.accept();
//handle client2
}
}.start();
Having client1 and client2 sockets you can handle them separately. Also, handling client connection should be done in a different thread so that you can serve multiple clients. Of course this code introduces a lot of duplication, but consider this as a starting point.
To wrap things up - if your goal is to implement HTTP GET and PUT, use servlet and get away from all this hustle.
A socket can only be open to a particular port, so you need multiple server sockets (e.g. 1 socket per port). I think you also need one thread per socket so that network activity on one socket doesn't interfere with activity on the others.
Are you implementing a server as an academic exercise? If not, I'd really really really really strongly recommend using a preexisting server, like Tomcat.
You could just open multiple server sockets of course.
You might also want to look at jboss netty which can help you implement protocols.
I try to play with sockets a bit. For that I wrote very simple "client" and "server" applications.
Client:
import java.net.*;
public class client {
public static void main(String[] args) throws Exception {
InetAddress localhost = InetAddress.getLocalHost();
System.out.println("before");
Socket clientSideSocket = null;
try {
clientSideSocket = new Socket(localhost,12345,localhost,54321);
} catch (ConnectException e) {
System.out.println("Connection Refused");
}
System.out.println("after");
if (clientSideSocket != null) {
clientSideSocket.close();
}
}
}
Server:
import java.net.*;
public class server {
public static void main(String[] args) throws Exception {
ServerSocket listener = new ServerSocket(12345);
while (true) {
Socket serverSideSocket = listener.accept();
System.out.println("A client-request is accepted.");
}
}
}
And I found a behavior that I cannot explain:
I start a server, than I start a client. Connection is successfully established (client stops running and server is running). Then I close the server and start it again in a second. After that I start a client and it writes "Connection Refused". It seems to me that the server "remember" the old connection and does not want to open the second connection twice. But I do not understand how it is possible. Because I killed the previous server and started a new one!
I do not start the server immediately after the previous one was killed (I wait like 20 seconds). In this case the server "forget" the socket from the previous server and accepts the request from the client.
I start the server and then I start the client. Connection is established (server writes: "A client-request is accepted"). Then I wait a minute and start the client again. And server (which was running the whole time) accept the request again! Why? The server should not accept the request from the same client-IP and client-port but it does!
When you close the server , the OS will keep the socket alive for a while so it can tell the client the connection has been closed. This involves timeouts and retransmissions which can take some time. You might find some info here and here. If you want your server to be able to immediately rebind the same socket, call setReuseAddress(true) on it, though it might be the client sockets that's in a TIME_WAIT state.
The socket is no longer in TIME_WAIT state, and can be reused again by any program.
Your client code just connects, closes the socket and then exits. As far as the server/OS tcp stack is concerned, these are different connections - it's fine to reuse the source port as long as any prior connection have been torn down. (Note that the OS might not tear down all of the housekeeping of the connection immediately after you call .close() or your program exits, there's some time delay involved so it can be sure all packets have been sent/received)
It is likely the operating system has not yet shutdown the sockets, try the netstat command (should work on Windows or Unix/Linux). If you run it immediately after you close client or server you should still the socket in "TIME_WAIT" "CLOSE_WAIT" or something similar. You wont be able to reuse those ports until they are fully closed.
Per Question #3: Many clients can connect to a server attached to a single port. Apache runs on port 80 but that doesn't mean only one person can view your website at a time. Also you are closing your client socket before you're opening a new one.