Hi!
I'm trying to create a client - server pair utilizing sockets, I need to repeatedly (and at a fast pace) connect and send data from the clients to the server.
However I'm running into some problems when running this code on a WinXP Pro machine (Linux seems to work fine).
After about 4000 connections the clients all fail with a java.net.BindException: Address already in use.
Any help would be appreciated, although I suspect this is an OS problem, I'd like to know wether any solutions/workarounds exist (other than modifying the machine setup itself).
Example code displaying the behaviour I describe above:
Server class
package test.socket;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
public class Reciever {
final static int PACKET_SIZE = 4096;
final static int PORT = 36712;
private final static void setup(ServerSocket ss) throws Exception {
// TODO set init server socket options
}
private final static void setupClient(Socket s) throws Exception {
// TODO set init client socket options
}
private final static void close(Socket s, InputStream is) throws Exception {
// TODO close client socket resources
if (is != null)
is.close();
if (s != null)
s.close();
}
public static void main(String[] args) throws Exception {
SocketAddress address = new InetSocketAddress(PORT);
byte[] buffer = new byte[PACKET_SIZE];
ServerSocket ss = new ServerSocket();
setup(ss);
ss.bind(address);
int count = 0;
while (true) {
Socket s = null;
InputStream is = null;
try {
s = ss.accept();
setupClient(s);
// grab inputstream and read data
is = s.getInputStream();
is.read(buffer);
// display "progress" so we see that something is actually
// happening
if (++count % 100 == 0) {
System.out.print(".");
System.out.flush();
}
} finally {
close(s, is);
}
}
}
}
Client class
package test.socket;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
public class Sender {
private final static class Writer implements Runnable {
private final SocketAddress address;
private final byte[] data;
Writer(SocketAddress address, byte[] data) {
this.address = address;
this.data = data;
}
public void run() {
while (true) {
try {
Socket s = null;
OutputStream os = null;
try {
s = new Socket();
setup(s);
s.connect(this.address);
// grab the output stream
os = s.getOutputStream();
// send data
os.write(this.data);
os.flush();
} finally {
close(s, os);
}
Thread.sleep(CLIENT_RESEND_DELAY);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
private final static int WRITERS = 10;
private final static long CLIENT_RESEND_DELAY = 10L;
private final static void setup(Socket s) throws Exception {
// TODO set init socket options
}
private final static void close(Socket s, OutputStream os) throws Exception {
// TODO close socket resources
if (os != null)
os.close();
if (s != null)
s.close();
}
public static void main(String[] args) throws Exception {
byte[] data = new byte[Reciever.PACKET_SIZE];
SocketAddress address = new InetSocketAddress("localhost", Reciever.PORT);
for (int i = 0; i < WRITERS; ++i)
new Thread(new Writer(address, data)).start();
}
}
Each writer thread fails with the follwing exception
java.net.BindException: Address already in use: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
at java.net.Socket.connect(Socket.java:519)
at java.net.Socket.connect(Socket.java:469)
at test.socket.Sender$Writer.run(Sender.java:28)