Le Burger
Le Burger

Reputation: 1

Sockets - Java Client and NodeJS Server

I am trying to connect a simple Java client to a NodeJS server but unfortunately things aren't working out that well. I took the client code from the Java Doc and only changed the hostname and port. Now my server is running on the same computer as the client and the port is 4555. If I do not have the same port on the client and the server then an error get thrown, I have checked this. Also if I change the hostname to something arbitrary(not localhost) in the client then a error get thrown. This suggests that if I am unable to connect then errors are getting thrown. The funny thing is that if I have the port set to 4555 and the hostname to "localhost" I am not getting any of theese errors and my client is working fine which makes me think that I am getting a connection but I am not getting the message "client connected" on my server side. Any suggestions?

The server code:

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var port = 4555;

app.get('/', function(req, res)
{
    res.sendFile(__dirname + '/index.html');
});

io.on('connection', function(socket)
{
    //When I connect to to localhost:4555 through the web browser(chrome)
    //this message is actually shown so the connection works there.
    console.log('client connected');
});

http.listen(port, function()
{
    //Message shown on program start
    console.log("app running");
});

The client code:

import java.io.*;
import java.net.*;

public class Main
{
    public static void main(String[] args) throws IOException
    {
        String hostName = "localhost";
        int portNumber = 4555;

        try (
            Socket echoSocket = new Socket(hostName, portNumber);
            PrintWriter out =
                new PrintWriter(echoSocket.getOutputStream(), true);
            BufferedReader in =
                new BufferedReader(
                    new InputStreamReader(echoSocket.getInputStream()));
            BufferedReader stdIn =
                new BufferedReader(
                    new InputStreamReader(System.in))
        ) {
            String userInput;
            while ((userInput = stdIn.readLine()) != null) {
                out.println(userInput);
                System.out.println("echo: " + in.readLine());
            }
        } catch (UnknownHostException e) {
            System.err.println("Don't know about host " + hostName);
            System.exit(1);
        } catch (IOException e) {
            System.err.println("Couldn't get I/O for the connection to " +
                hostName);
            System.exit(1);
        } 
    }
}

Upvotes: 0

Views: 3897

Answers (1)

jfriend00
jfriend00

Reputation: 708156

To get your "client connected" message, you need a successful socket.io connection. socket.io is a messaging data format built on top of the webSocket protocol. So to successfully connect to a socket.io server, you need a socket.io client. You cannot connect to a socket.io server with a plain TCP client which is what you appear to be trying to do.

Just to give you an idea of what's likely happening here, a socket.io expects an incoming webSocket connection (which starts life as an HTTP connection which is then "upgraded" to the webSocket protocol because of some special headers on the incoming HTTP connection. The socket.io adds its own data format on top of the webSocket data frame. So, only a socket.io client can talk to a socket.io server. The socket.io server is rejecting the incoming connection after it connects because the initial data on the connection does not fit the proper format.

See Writing webSocket Servers to give you an idea what is involved in connecting to a webSocket server. There's an initial connection request format using HTTP, there's an upgrade request, there are security headers, then there's an upgrade to the webSocket protocol, then there's a data frame format with encryption and then socket.io then adds a message data format on top of all this. When your client tries to connect to a server expecting all this, the server just says this is garbage and drops the connection.

If you want a plain TCP connection, then you can use a plain TCP server in your node.js server and connect to that. You want a socket.io connection, then you can get a socket.io client library for Java and use that instead of your plain Socket to talk to your socket.io server.

Upvotes: 3

Related Questions