Max connections on a port - java

I am trying to implement a web socket server in java. The code for the server is :-
ServerSocket serverSocket = new ServerSocket();
SocketAddress socketAddress = new InetSocketAddress(9000);
LOGGER.info("Listening on port :: 9000");
serverSocket.bind(socketAddress,5 );
while (true) {
Socket socket = serverSocket.accept();
Processor processor = Processor.getInstance(processorCounter++);
try {
processor.begin(socket);
} catch (AppException e) {
LOGGER.info(e.getMessage(), e);
}
}
I am creating a new thread Processor which accepts the socket and begins to publish response on it without closing the connection. The connection is long-term and persistent.
When I hit this server with around 2000 requests, I observe that no more than 249 threads are getting created. The question is that why no more than 249 threads/processors are being spawned?
PS.:
requests are being sent from Google Chrome
Javascript that makes the request -
const func1=function(){
for(var i=1;i<=2000;i++){
var ws=new WebSocket("ws://localhost:9000");
ws.onopen=function(event){
ws.send("are you a teapot?! from client "+i);
};
ws.onmessage=function(event){
console.log("Server says : "+event.data);
};
ws.onerror=function(event){
console.log("error () -> "+JSON.stringify(event));
};
ws.onclose=function(event){
console.log("close () -> "+JSON.stringify(event));
};}
}

Related

Java Sockets + socket.io-client (Angular 13) = Failed connections and scrambled messages

I am trying to use a Java Socket Server with socket.io-client, but it has an erratic behavior from the moment of the connection. It manages to stablish connection, but then this exception is thrown in Angular:
GET https://127.0.0.1:1532/socket.io/?EIO=4&transport=polling&t=N__rEfS net::ERR_SSL_PROTOCOL_ERROR
And the Server in Java only receives scrambled text repatedly
and the Client starts connecting and disconnecting over and over again. Why is this happening? Is there any way to get a cleaner Socket connection from Angular 13 to Java?
I use this Java Socket Server for many other applications and it works perfectly for everything else but this.
This is the routine that reads the Java Server:
void handleClientRequest() {
try{
mBufferIn = new BufferedReader(new InputStreamReader( socket.getInputStream()));
mBufferOut = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
//in this while the client listens for the messages sent by the server
while (clientRun) {
String clientMessage = mBufferIn.readLine();
if (clientMessage != null && mMessageListener != null) {
mMessageListener.messageReceived(clientMessage);
}
}
} catch(Exception e){
System.out.printf("%s: Unexpected client disconnection. Reason:%n", accountId);
e.printStackTrace();
}
}
And this is the Angular code:
this.socket = io('https://127.0.0.1:1532');
this.socket.on('connect', () => {
const engine = this.socket.io.engine;
console.log(engine.transport.name); // in most cases, prints "polling"
engine.once('upgrade', () => {
// called when the transport is upgraded (i.e. from HTTP long-polling to WebSocket)
console.log(engine.transport.name); // in most cases, prints "websocket"
});
engine.on('packet', ({ }) => {
// called for each packet received
});
engine.on('packetCreate', ({ }) => {
// called for each packet sent
});
engine.on('drain', () => {
// called when the write buffer is drained
});
engine.on('close', (reason: any) => {
// called when the underlying connection is closed
});
});
Code taken from https://socket.io/docs/v4/client-socket-instance/
Socket IO is a communication protocol implemented on the top of websocket
from my understanding (correct me if im wrong) you are using raw socket in java.
So very likely that "scrambled" text that you are receiving, is part of https handshake.
My suggestion as way forward, will be to use library that handles websocket connections.

Java-Client connecting to C# Server: Connection Timeout

I am trying to connect two Android devices to a c#-server and I always get a connection timeout.
The java-code is simple:
Socket socket = new Socket(mAddress, PORT);
If I start a java-server on the pc then the connection is successful. So its not a network/firewall problem.
But my c#-server just won't accept any connections, code:
private TcpListener serverSocket;
private TcpClient clientSocket1;
private TcpClient clientSocket2;
private void Form1_Load(object sender, EventArgs e)
{
serverSocket = new TcpListener(IPAddress.Any, port);
clientSocket1 = default(TcpClient);
clientSocket2 = default(TcpClient);
serverSocket.Start();
clientListenerThread = new Thread(wait4Clients);
clientListenerThread.Start();
}
private void wait4Clients()
{
logToConsole("Clientlistener started");
clientSocket1 = serverSocket.AcceptTcpClient();
logToConsole("Client No 1 started!");
clientSocket2 = serverSocket.AcceptTcpClient();
logToConsole("Client No 2 started!");
}
I also tried System.Net.Sockets.Socket instead of System.Net.Sockets.TcpClient, didnt worked either.
Thanks a lot
EDIT: Seems the code is perfectly fine. If I run the exe and not debug mode via Visual Studio, everything works. So the debug mode somehow prevents the server socket from working correctly. Any ideas why this happens?
// TCP Server C#, look at [msdn][1]
try
{
// Set the TcpListener on port 8080 of Any IP Address.
TcpListener server = new TcpListener(IPAddress.Any, 8080);
// Start listening for client requests.
server.Start();
// Buffer for reading data
Byte[] bytes = new Byte[1024];
String data = null;
// Enter the listening loop.
while(true) {
Console.Write("Waiting for a connection... ");
// Perform a blocking call to accept requests.
// You could also user server.AcceptSocket() here.
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("Connected!");
// Get a stream object for reading and writing
data = null;
NetworkStream stream = client.GetStream();
int i;
// Loop to receive all the data sent by the client.
while((i = stream.Read(bytes, 0, bytes.Length))!=0)
{
// Translate data bytes to a ASCII string.
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine("Received: {0}", data);
// Process the data sent by the client.
data = data.ToUpper();
byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);
// Send back a response.
stream.Write(msg, 0, msg.Length);
Console.WriteLine("Sent: {0}", data);
}
}

Server Sent Events Android

I want to use Server Sent Events in my WebView on Android (4.4). The EventSource should connect to a local Port (5003) where I have a ServerSocket listening for incoming requests:
Socket _socket;
//Creating Server Socket listening on Port 5003
try {
InetAddress adress = InetAddress.getByName("localhost");
ServerSocket serversocket = new ServerSocket(5003, 50, adress);
while(true){
_socket = serversocket.accept(); //Accept incoming request
Logger.Log.d("SSE","Received Server Sent Event Request);
}
} catch (IOException e) {
e.printStackTrace();
}
The JavaScript from my HTML Page:
var source = new EventSource('http://localhost:5003/');
source.addEventListener('message', function(e) {
console.log(e.data);
}, false);
source.addEventListener('open', function(e) {
// Connection was opened.
console.log('open');
}, false);
source.addEventListener('error', function(e) {
var txt;
switch( event.target.readyState ){
// if reconnecting
case EventSource.CONNECTING:
txt = 'Reconnecting...' + event.target.url;
break;
// if error was fatal
case EventSource.CLOSED:
txt = 'Connection failed. Will not retry.';
break;
}
console.log(txt);
}, false);
The EventSource doesn't connect to my local socket.
Every 3 seconds the onError is called and the EventSource tries to reconnect.
I/chromium(15898): [INFO:CONSOLE(24)] "Reconnecting...http://localhost:5003/"
Can anybody please help me?
I solved the problem myself.
The code is working. I only had to reset my Android device to factory defaults.
Now everything works perfectly.

Java serversocket not detecting lost connection

I have a socket client (on android phone) and server (on PC) both on a wifi network and the server successfully reads data from the client.
However, when I turn off the wifi on the phone the server read just hangs, whereas I was hoping some error would be thrown.
I do have setSoTimeout set on the server, but the read is not timing out.
On the PC netstat still shows an established connection
netstat -na | grep 6668
TCP 192.168.43.202:6668 192.168.43.26:43076 ESTABLISHED
Is there a way to tell if the client host has disappeared, or getting the read to time out?
Here is the server read
if (ss.isConnected()) {
try {
readData();
} catch (java.net.SocketTimeoutException ex) {
logger.warning(ex.toString());
} catch (InterruptedIOException ex) {
logger.warning(ex.toString());
} catch (IOException ex) {
logger.log(Level.WARNING, "Data communication lost will close streams - IOEx - socket status {0}", ss.socketStatus());
closeStreams();
} catch (Exception ex) {
logger.log(Level.WARNING, "Data communication lost will close streams - Ex - socket status {0}", ss.socketStatus());
closeStreams();
}
}
Where readData is,
public void readData() throws IOException {
for (int i = 0; i < data.length; i++) {
data[i] = ss.readDouble();
}
}
ss.readDouble() is,
public double readDouble() throws IOException {
return in.readDouble();
}
And the server connection,
public void connect() throws IOException {
if (serverSocket == null || serverSocket.isClosed()) {
init();
}
logger.log(Level.INFO, "Wait on " + serverSocket.getLocalPort());
server = serverSocket.accept();
serverSocket.close();
logger.log(Level.INFO, "Connected to {0}", server.getRemoteSocketAddress());
out = new DataOutputStream(server.getOutputStream());
in = new DataInputStream(server.getInputStream());
}
Make a timeout, so let's say no data has been sent for 10 minutes, close it in 60 seconds!
Setting a timeout for socket operations
The answer for this question may help you.
This is nature of TCP connection, not java sockets per se. If the remote peer disconects with broken connection, how should your server know that the peer simply has no data to send?
Writting on closed socket will cause exception, read will simply block if client doesnt end tcp connection properly, for the reason above.
If you go through socket API, you will find option to set timeout ( before proceeding with blocking operation).
You could also consider TCP KEEP Alive, which is also exposed by the Socket API.
// Edit: additional information as per the OP comment
When your client connects to server, you create a client socket to communicate with the peer. Your server socket is the one at which you are listening for new client connections. It is the client socket at which you specify keep alive or read timeout because this is the socket from which you read/write.
// your server is actually reference to ClientSocket
server = serverSocket.accept();
// keep alive duh
server.setKeepAlive(true);
serverSocket.close();

Threading in client-server socket program - proxy sever

I am trying to write a program that acts as a proxy server.
Proxy server basically listens to a given port (7575) and sends the request to the server.
As of now, I did not implement caching the response.
The code looks like
ServerSocket socket = new ServerSocket(7575);
Socket clientSocket = socket.accept();
clientRequestHandler(clientSocket);
I changed the above code as below: //calling the same clientRequestHandler method from inside another method.
Socket clientSocket = socket.accept();
Thread serverThread = new Thread(new ConnectionHandler(client));
serverThread.start();
class ConnectionHandler implements Runnable {
Socket clientSocket = null;
ConnectionHandler(Socket client){
this.clientSocket = client;
}
#Override
public void run () {
try {
PrxyServer.clientRequestHandler(clientSocket);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Using the code, I am able to open a webpage like google. However, if I open another web page even I completely receive the first response, I get connection reset by peer expection.
1. How can I handle this issue
Can I use threading to handle different requests. Can someone give a reference where I look for example code that implements threading.

Categories