Java Networking - Common Socket Exceptions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search

Internal

Overview

These socket issues arise out of application bugs, system settings or system load.

java.net.SocketException: No buffer space available (maximum connections reached?)

This exception is usually observed when connections are being made at a rapid rate. This exception can arise due to one of the following conditions:

  1. When the number of available ephemeral network ports available for the application are nil.
  2. When the system does not have enough main memory to support new connections (whenever a socket is created, a part of memory is allocated for its READ/SEND buffers from non-paged kernel memory).

Solution: In Windows, the number of ephemeral network ports can be increased as directed here to resolve the problem arising out of case 1). The only available solution for case 2) is to make sure that the network connections are closed properly by the applications. And make sure the rate at which the connections are created does not throttle the kernel memory. Currently there are no formally documented approaches available to increase non-paged kernel memory.

java.net.SocketException: Broken pipe (UNIX)

A broken pipe error is seen when the remote end of the connection is closed gracefully.

Solution: This exception usually arises when the socket operations performed on either ends are not sync'ed.

java.net.SocketException: Connection reset

This exception appears when the remote connection is unexpectedly and forcefully closed due to various reasons like application crash, system reboot, hard close of remote host. Kernel from the remote system sends out a packets with RST bit to the local system. The local socket on performing any SEND (could be a Keep-alive packet) or RECEIVE operations subsequently fail with this error. Certain combinations of linger settings can also result in packets with RST bit set.

java.net.SocketException: Too many open files

An attempt was made to open more than the maximum number of file descriptors allowed in this process. These file descriptors include various other entities along with sockets. This is implementation dependent and could be either globally, per process, or per thread. On Linux, this is designated by the number OPEN_MAX.

Solution: Monitor the application and keep a watch on this. These values may be configurable on certain implementations. On Linux, ulimit can be used.

=java.net.BindException: Address already in use: JVM_Bind/java.net.BindException: Address already in use: NET_Bind

In the case, where the exception arises while doing a socket bind. The reason is that the application is trying to bind a socket to a port/IP/protcol combination that is already in use.

Solution: Avoid this. netstat log will be of help in this case to confirm.

java.net.BindException: Address already in use: connect

In the case, where the exception arises while doing a socket connect. There are several explanations for this some of them complex, depending on the implementation. Nonetheless, the problem can best be summarized that no local port numbers are available to the client. This could be because there are a lot of active connections in the local system(also involves sockets in a reuse connections phenomenon) . Or a lot of ports are in TIME_WAIT state(period between closing a connection and releasing the resources).

Solution: Increase the number of available ports. But if the problem is that there are not many concurrent active connections but in TIME_WAIT state, then reducing the TIME_WAIT value is a solution. This is platform dependent. Please consult the OS documents more information.

java.net.SocketTimeoutException: connect timed out

Signals that a timeout has occurred on a socket read or accept. That means that this exception emerges when a blocking operation of the two, an accept or a read, is blocked for a certain amount of time, called the timeout. Let’s say that the socket is configured with a timeout of 5 seconds. If either the accept() or read() method, blocks for more than 5 seconds, a SocketTimeoutException is thrown, designating that a timeout has occurred. It is important to note that after this exception is thrown. the socket remains valid, so you can retry the blocking call or do whatever you want with the valid socket.

Hang in Socket Write call

This happens when the sockets write buffers do not contain enough free space to accommodate the send data. This usually means the other side of the connection is not reading the data. Another typical situation is that the other side of the connection died and our side is attempting to retransmit. The retransmit attempts will eventually run out and the write will unblock. These timeouts are usually 15 - 17 minutes, and it's due to the exponential backoff retransmit:

Also see

SO_KEEPALIVE

TODO: