Java: How to clear socket bindings - java

I am having a few issues with sockets within my Java SIP client. When I bind to an address and port, if something goes wrong I have to attempt to reconnect, usually after I've stopped and restarted the process. Problem with that is then the port is bound and I am forced to increment the local port.
How can I remove the binding to the port I am targeting before binding to it?
If that isnt possible, then how can I trap the process just before it ends so that I can locate the socket binding and close it manually?
#Jason - Jason, but in this case I am writing the Client and have no access to the server, the port I am referring to is on the client and is local. Is there a way to flush the port binding before attempting to connect? If not is there a way to trap the process interrupt, as in perl there is a way to trap a 'die' signal and do some post processing, does Java have this? If so I could call close() on the socket connection

In my experience 9 times out of 10, the answer to this class of problem is, "Look up SO_LINGER".
If you pull the plug (literally) on a client, the server optimistically hopes it will come back to collect the data you already sent on that socket. So it holds onto that data, and the port, until the buffers clear.
Usually on the server you want to kill these buffers with extreme prejudice, due to the sort of DOS attack (intentional or accidental) you just discovered.

Don't fiddle with SO_LINGER, it just adds insecurity. The real question is why are you binding to a local port at all?

Ok - I found a way to trap Java signals by reading this tutorial online - http://www.ibm.com/developerworks/java/library/i-signalhandling/
This way one can trap the die signal and close the connection.

Related

java help understanding how socket connections work

I am completely new to creating a network connection in java so I apologize if this is a stupid question.
I am trying to create a D&D companion in java that will allow a player to create their character and then send it to the DM so that they can view it and make changes and send it back to the player. I want to be able to make it so that any time a field is changed on one computer it will also be changed on the other computer.
After a bunch of research online I have been able to create a socket connection between the DM(server) and the player(client) and pass a message between the two but I am not sure how a socket connection works after this initial connection is made. My research has not been very clear on this. I have found many resources that have said that java closes the socket after a message has been passed and many that say that the socket stays open.
If java closes the socket then my problem is easy enough to solve because then I will just have to open a new socket every time I need to pass data making sure that I pass the IP address of the client to the server the first time I make a connection.
My real questions come in when a socket stays open.
If the socket stays open and multiple clients connect to the server, will the server just shout over the network whenever it transmits a message so that all clients receive the message? (If this is the case then I know I can just attach a username to the front of the message so that the client can determine if the server is talking to it.)
If the server does not shout then how do I specify which client I want the server to talk to?
Will I have to add a loop to my receive methods so that the client/server is constantly listening for a transmission from the server/client or will java automatically do so after I run the method the first time?
I have found many resources that have said that java closes the socket after a message has been passed
You found them where?
and many that say that the socket stays open.
All those are correct. Java never closes connections. The application closes connections.
If java closes the socket then my problem is easy enough to solve because then I will just have to open a new socket every time I need to pass data making sure that I pass the IP address of the client to the server the first time I make a connection.
It doesn't.
My real questions come in when a socket stays open.
If the socket stays open and multiple clients connect to the server, will the server just shout over the network whenever it transmits a message so that all clients receive the message?
No. It will respond via the socket that is connected to the corresponding client.
(If this is the case then I know I can just attach a username to the front of the message so that the client can determine if the server is talking to it.)
Unnecessary.
If the server does not shout then how do I specify which client I want the server to talk to?
The server responds via the same socket it read the request from.
Will I have to add a loop to my receive methods so that the client/server is constantly listening for a transmission from the server/client
No, you will have to add a thread per accepted socket, that loops reading requests until end of stream.
or will java automatically do so after I run the method the first time?
No.
You seem to have been reading some truly appalling drivel. Take a look at the Custom Networking section of the Java Tutorial.
Adding to EJP's wise answer, it might be worth clarifying:
Sounds like you (wisely) use TCP, so your Socket represents a connection between 1 server and 1 client. No "shouting". In examples such as this , when connection is established (namely, client obtains a Socket by calling "new Socket" and server obtains a Socket by calling "accept"), those Sockets are dedicated to those 2 specific endpoints. So if 10 clients connect to 1 server, the server will keep 10 Sockets and won't mix them up. A bit like a poor secretary that has 10 phones on his desk and answers them all - despite the mess, each earpiece is clearly connected to 1 customer.
The connection can hold for a while & serve several messages. It will terminate when either one of the sides calls 'socket.close', or it can be terminated by underlying 3rd parties (operating system, proxies, firewalls).
For your first version, or for simple business requirements, it's probably enough to converse over this 1 simple connection. However, for commercial critical data that requires 'assurance of delivery', you might need to invest some careful thought & possibly tools such as RabbitMQ.
Good luck:)

How to keep sending messages in websockets even when the network is down?

I am using the java implementation of websockets(org.java_websocket). I am using "ifconfig l0 down" to simulate a network failure. I would like the server to keep sending messages even when the network is down and resend them(through tcp mechanism) once the network is up again. However, the java implementation has the following check in the send function
private void send( Collection<Framedata> frames ) {
if( !isOpen() )
throw new WebsocketNotConnectedException();
which leads to
an error occured
close a stream
Exception in thread "main" org.java_websocket.exceptions.WebsocketNotConnectedException
as soon as I simulate connectivity loss between the server and client.
Since I am not properly calling the close() function in websockets I feel the TCP mechanism should work for some time before timing out leading to websockets layer to close the connection. Am I expecting something outwordly? Is there an implementation that can help me?
It is not a good idea to simulate network connectivity problems by ifconfig down because the operating system knows the interface status. The OS then may (and it does) a handle connectivity error and an interface error differently and a network application gets different error indication.
An option how to simulate a connectivity errors on a linux box is iptables. Let say your application uses the port 80. You can drop all communication to/from port 80 via
iptables -A INPUT -p tcp --destination-port 80 -j DROP
iptables -A OUTPUT -p tcp --source-port 80 -j DROP
The traffic drop in iptables is handled like a network outage.
I think your test setup here does not really do what you want. I guess what happens is that as soon as you are using ifconfig the operating system is smart enough to look up which sockets are bound to this interface and closes them. Thereby Java and the websocket application get notified about the closed socket and the websocket connection gets cleaned up.
You probably need another way to simulate an "unplugged" connection, in the sense of you want to see a high packet loss/latency but without an actual connection close notification.
It is so late for answering to this question, but I think my answer can help another guys:
you should use
connectBlocking()
instead of
connect()
function. note that connectBlocking() , block your thread!

Server-push or client-request? TCP or UDP?

I'd like to implement a function of realtime message such as chatting in facebook but several questions confuse me:
1. To reduce overhead of server and make it really 'realtime', I should use a full-duplex way of communication like socket instead of Ajax, is that right?
2. If I use socket, which protocol should I choose, TCP or UDP?
3. Assuming that I am using TCP, will server keep trying to resend the lost packages so that it would take much overhead?
4. What if the network failed in a communication between server and a client? Will the socket close it self or I should handle with several kinds of network conditions?
Can anyone help?
You can use WebSockets. XMLHttpRequest is probably obsolete now for anything real-time (because it's not real-time), though you could fall back to using it for people who use a browser that doesn't support WebSockets
Use UDP if the information you are sending is only valid for the time it is sent, for example in games that would be the position of the players (you don't care to receive the position they were in 5 seconds ago). Besides, you can't use UDP with WebSockets
For anything other than that, use TCP (unless you do hole punching to achieve p2p), because loss of data is probably bad for you, and TCP handles that.
You would have to check for and resend lost data manually with UDP anyway, unless failure in communication is acceptable by you
You will get an IOException. If the connection was closed improperly the exception will be thrown after a timeout of unresponsiveness that you are able to change according to your needs. This is assuming you use TCP, otherwise you should figure out yourself when you consider clients connected or disconnected according to the responses/data you receive (or not receive).

How to identify a broken socket connection in Java immediately?

I have a typical java client and a server. The client sends some request to the server and waits for the response. The client reads up to say 100 bytes of data from the contained input stream into an array of bytes. It waits for the complete response of 100 bytes to be read within a specified timeout period of say 3 secs. The problem here is to identify if the server went down or crashed while/before writing the response. Basically, we need to identify if the socket was broken or the peer disconnected for some reason. Is there a way to identify this?
How to identify a broken socket connection in Java immediately?
You can't detect it immediately, in Java or any other language. TCP/IP doesn't know, so Java can't know. The only sure way to detect a broken TCP connection is by writing to it and catching IOExceptions, and they won't happen immediately.
The best way to identity the connection is down is to timeout the connection. i.e. you expect a response in a given amount of time and flag if that response does not come as you expect.
When you have a graceful disconnection (.e.g the other end calls close()) the read on the connection will let you know once the buffer has been drained.
However, if there some other type of failure, you might not be notified until the OS times out the connection (e.g. after 3 minutes) and indeed, you may want to keep the connection. e.g. if you pull the network cable out for 10 seconds and put it back in, that doesn't need to be a failure.
EDIT: I don't believe its a good idea to be too aggressive in automatically handling connection/service "failures". This is usually better handled by a planned fix to the system, based on investigation of the true cause. e.g. increased bandwidth, redundant connectivity, faster servers, code fixes.
If connection is broken abnormally, you will receieve IOException when reading; that normally happens quite fast, but there is no guarantees about time - all depends on the OS, network hardware, etc. If remote end gracefully closes the socket, you'll read -1 as next byte.
Assuming everything else works, if the remote peer - the TCP server - was killed then the TCP client will normally receive a TCP RST (reset) and you'll get an IOException in your client application.
However, there are lots of other things that can go wrong besides a process being killed. Basically anything on the network path between the two processes: a cable is yanked, a router dies, a firewall dies, etc. All of this will not immediately be detected.
For the above reasons the general rule is - as pointed out in the answer from EJP - that a broken connection can only be detected by writing to it. This is why it is always recommended that a TCP client and TCP server exchange some type of heartbeat messages at regular intervals. There are different ways to do this. I like best the method where the TCP client will - in the absence of data being received from the TCP server - send a heartbeat message to the server and expect a reply back within a certain time period. This way heartbeat messages will only be sent when really needed.
A sub-optimal approach - if you cannot implement true heartbeating - is to always read with a timeout. Set the timeout on the socket and then catch java.net.SocketTimeoutException. This will allow you to know that no data has been received on socket during x milliseconds.
It should be mentioned that there's one scenario where you don't have to use heartbeating, nor using the socket timeout: if the TCP client and the TCP server communicate over a loopback interface then a broken connection will always be propagated to both the TCP client application and the TCP server application. This is because, in this case, there's really no network infrastructure between the two processes. So if you have an existing application which isn't well-designed with respect to its TCP communication (i.e. it doesn't implement some form of heartbeating or at least reading with a timeout), then as a last resort you may 'fix' the problem by moving the two application onto the same host and let them communicate over the loopback interface.

Question regarding TCP Connection Forcefully shut down

I am designing a Client Server Chat application in Java which uses TCP connection between them. I am not able to figure out how to detect at server side when a client forcefully closes down. I need this as i am maintaining a list of online clients and i need to remove user from the list when he forcefully closes the connection.
Any help will be highly appreciated.
Thanks
Tara Singh
One way to receive timely notification of a disconnect is to attempt to send a small piece of information at regular intervals. Then, the latest that you'll know of a client disconnect is at most your interval. People call this a heartbeat.
Assuming that your server is using a java.net.Socket, you can query the socket from time to time, it provides methods isClosed() and isConnected().
It depends on how you're handling your socket I/O
For example, if you're using a selector (java.nio) to do non-blocking I/O on a set of sockets you're going to find out about any disconnects the next time you call select().
Maybe if you updated your question with how you're handling the sockets?

Categories