Sockets - Java Client and NodeJS Server - java

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);
}
}
}

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.

Related

Client Socket as the listener?

I need all my clients attached to a server to be socket listeners. The server will attempt to connect to a specific client and instruct it to preform a various task via a socket message. So my question is, can my Java Client be the ServerSocket and listen for Server requests? And is it possible for a webpage loaded on a client machine to know the clients IP address to send the message too. We have an application running on our server that has many clients attached and when a button is pressed on the clients webpage it will attempt to connect with this client and send a message to it. Most of the time servers are listeners, but in our case we need just opposite where the client is listener waiting for server requests. But the server needs to know what the client IP address is to establish the connection since our clients are attached via DHCP.
Btw,
All our clients are basically running a webpage from our server and each client has it own PC. The thing I need to do is control a USB device on each client machine. I have control over the website software, so my goal was to use sockets to do this since controlling a clients external hardware is very difficult remotely. So what I was going to do is write a Java app and that runs on the client machine acting as a listener which when someone presses a button on the webpage the server will attempt to connect to the client machine and send the message down to it. I’m just not sure how to handle this from the server side, so it knows what client it’s talking too since I don’t want to broadcast the message to all clients, but only the one the button was pressed on, keep in mind each client is attached via DHCP addressing, so I can't hardcode the hostID. I can attach java/groovy or ajax scripts to the button event on the server side, but I’m not sure how to setup the socket protocol on the server to make this work.
Here is an example of a socket connection I could use on the client / server side, but I need to know the clients DHCP IP address is to make it work properly.
Server side requesting client task
public void requestSocket()
{
Socket socket = null;
private BufferedReader in = null;
private PrintWriter out = null;
//Create socket connection for server
String serverAddress = "localhost"; // Needs to be the client DHCP IP address.
try
{
socket = new Socket(serverAddress, 4444);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
catch (UnknownHostException e)
{
System.out.println("Unknown host: " + serverAddress);
System.exit(1);
}
catch (IOException e)
{
System.out.println(e);
System.out.println("No I/O");
System.exit(1);
}
}
Client side listener acting as the server
public void listenSocket()
{
int portNumber = 4444;
ServerSocket server = null;
Socket client = null;
BufferedReader in = null;
PrintWriter out = null;
try
{
client = new ServerSocket(portNumber);
}
catch (IOException e)
{
System.out.println("Could not listen on port " + portNumber);
System.exit(-1);
}
try
{
server = client.accept();
}
catch (IOException e)
{
System.out.println("Accept failed :" + portNumber);
System.exit(-1);
}
try
{
in = new BufferedReader(new InputStreamReader(server.getInputStream()));
out = new PrintWriter(server.getOutputStream(), true);
} catch (IOException e) {
System.out.println("Read failed");
System.exit(-1);
}
while(true)
{
try
{
line = in.readLine();
//Send data back to client
out.println(line);
}
catch (IOException e)
{
System.out.println("Read failed");
System.exit(-1);
}
}
}
Can anyone help answer these questions?
First: what are your clients? Java Client or Webpage in browser?
Second: if it is JavaClient it can be only ServerSocket in it to listen what your server will tell and Server must know IP and port of each clients to do that.
Third: for Java Client actually JMS with Topic is there for such tasks. Server publishes message, while clients listen and do with message what is needed.
and Forth:
If it is a webpage there is only one way - from JavaScript (or auto-refresh mechanism) browser can ask Server periodically (by timer) for new messages. With HTML there is no way for the server to initiate any actions on client browser.
It is always request-response.
Updated:
try something like that:
<html>
<head>
<title>Test Loop Back</title>
</head>
<body>
<form action="http://localhost:4444" id=in_form>
<table>
<tr>
<td>
<label>IN_MSG:</label>
</td>
<td>
<input type="text" name="IN_MSG" id="IN_MSG"/>
</td>
</tr>
</table>
<button type="submit" formmethod="post">Post Something</button>
</form>
</body>
</html>
and see what you get in your background Java listening on port 4444. Mayb it can be enough? you can pass anything you may need as separate input fields and them can be hidden as well as whole form can be invisible...
If you need some data from server prepared for background java think the way on picture to avoid communication from server to background java.
main point is to avoid direct communication from server to background java. All passes through the browser, so no pain with IP, ports, proxy, security etc. Browser and javascript on webpage take care of all...

How to run a simple socket server that allows incoming connections?

I am trying to build a very simple socket server in JAVA that my Flash application can listen to. I am using this tutorial. Everything seems to be working - the JAVA code is compiled and the server is running.
My question is: how can external applications send messages to this server using just an IP address and a port number? My goal is that flash can listen to socket messages sent by an external application.
The Java code:
import java.io.*;
import java.net.*;
class SimpleServer {
private static SimpleServer server;
ServerSocket socket;
Socket incoming;
BufferedReader readerIn;
PrintStream printOut;
public static void main(String[] args) {
int port = 8080;
try {
port = Integer.parseInt(args[0]);
} catch (ArrayIndexOutOfBoundsException e) {
// Catch exception and keep going.
}
server = new SimpleServer(port);
}
private SimpleServer(int port) {
System.out.println(">> Starting SimpleServer");
try {
socket = new ServerSocket(port);
incoming = socket.accept();
readerIn = new BufferedReader(
new InputStreamReader(
incoming.getInputStream()));
printOut = new PrintStream(incoming.getOutputStream());
printOut.println("Enter EXIT to exit.\r");
out("Enter EXIT to exit.\r");
boolean done = false;
while (!done) {
String str = readerIn.readLine();
if (str == null) {
done = true;
} else {
out("Echo: " + str + "\r");
if(str.trim().equals("EXIT"))
done = true;
}
incoming.close();
}
} catch (Exception e) {
System.out.println(e);
}
}
private void out(String str) {
printOut.println(str);
System.out.println(str);
}
}
Maybe I don't understand correctly your problem description, but if you create the server in Java, it listens to its port and not your Flash application. If you want your Flash application to wait for messages from other applications, it must have a server role and listen to a TCP port the same way as this Java server does.
You can connect to and test the given Java server easily by telnet program (available in all operating systems) by providing a host name or an IP address and a port as parameters:
telnet 127.0.0.1 8080
Any other application can connect in a similar way, using just a hostname/IP address and a port. For example in Java, you can create a client socket:
Socket clientSocket = new Socket("localhost", 8080);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
By not specifying an IP address for your socket, it will listen on 0.0.0.0 (all interfaces).
In fact, that will usually be your computer's IP / the server's IP.
Assuming that your application runs on your computer at home, there are three cases that cover most of the connection situations:
Connecting from the same machine:
Use 127.0.0.1:8080
Connecting from the same LAN (e.g. your brother's PC):
Use your LAN IP (e.g. 192.168.1.4:8080)
Connecting from WAN (outside your routers LAN) (internet e.g.):
Use your WAN IP.(e.g. 84.156.74.194). There are plenty websites, that tell you your WAN IP like this
You may have to setup your router, to forward the port 8080 to your PC
For simple connection tests, one could use a telnet client.
I think you are missing the point of client/server socket applications.
If you are building the socket server (with whatever programming language you chose), you will then need to connect with (a) socket client(s) to this server. After a connection is successfully established (persistent) between the client and the server, you can start what ever kind of communication you have implemented between them.
The server always acts as the passive, the client as active part in a socket server/client constellation.
I was checking the link that you are referring to. In that, the procedure to create a stand-alone server is mentioned which is the code that you have pasted as well.
According to the link, the application acts as the client and uses the XMLSocket methods to connect to this server. This application is the flash application that you are talking about. As mentioned in the link, by using the following code any flash application can connect and talk to the server:
var xmlsock:XMLSocket = new XMLSocket();
xmlsock.connect("127.0.0.1", 8080);
xmlsock.send(xmlFormattedData);
When you mention
My goal is that flash can listen to socket messages sent by an external application.
its actually the flash application that is the client and it cannot listen unless programmed to act as a server. I hope this provides some clarity!

Android Java Socket - Connection timed out

I'm trying to create one simple app. I want to my cell phone be a server socket and I'm trying to send messages from my pc, my pc is the client is this case.
When they are in the same network it works fine but when I connect my cell phone in a 3G network I receive the error "Connection timed out" in my PC.
I'm using a host from no-ip (in both situation). When I do 'telnet mycellphonehost.org 8080' for example I have no problem, it is able to connect. I think the no-ip host is working fine because is give me the correct external IP.
I also use one app called FIREBIND for test if the port is open or not. The result is: "Firebind was successfully able to both transmit and receive data over this port using the TCP protocol."
I already read a lot questions about this subject, similar problems... but nothing help me solve this issue. I hope someone can help me. Thanks in advance!
Follow the codes:
Android Server
try{
ServerSocket server = new ServerSocket(port);
Socket s = server.accept();
BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
System.out.println(input.readLine());
input.close();
s.close();
server.close();
}
catch(IOException e){
System.out.println("ERROR: " + e.getMessage());
}
PC Client
try{
Socket s = new Socket("myhostfromno-ip.org",port);
PrintStream output = new PrintStream(s.getOutputStream());
output.println("TEST MESSAGE");
output.flush();
s.close();
}
catch(IOException e){
System.out.println("ERROR: " + e.getMessage());
}
PS: They have to be in different network
I would recommend using GCM for the cell
Notification and afterwards making a server pull. It certainly is much faster and you could use a simple REST server for serving data.
You need to make your PC the server and your droid the client.

WebSocket in Firefox establish two connection

I'm coding a WebSocket server in Java. When I use WebSocket to connect to the server in firefox, I found two connection were established, and one of them never send any data...
My firefox version is 15.0.1
The same code run in Chrome is OK, connect once, established only one connection.
Does anybody have the trouble like this?
There is the server's code:
ServerSocket svrSock = new ServerSocket();
svrSock.bind(new InetSocketAddress("0.0.0.0", 11111));
while(true) {
try {
// accept connection
Socket clientSock = svrSock.accept();
// print the socket which connected to this server
System.out.println("accept socket: " + clientSock);
// run a thread for client
new ClientThread(clientSock).start();
} catch (Exception e) {
e.printStackTrace();
}
}
And there is the js code:
var url = 'ws://localhost:11111/test/';
var ws = new WebSocket(url);
ws.onopen = function(){
console.log('connected!');
ws.send(11111);
ws.close();
};
ws.onclose = function(){
console.log('closed!');
};
When I run this js code in firefox, I get this in my server console:
accept socket: Socket[addr=/127.0.0.1,port=56935,localport=11111]
accept socket: Socket[addr=/127.0.0.1,port=56936,localport=11111]
This is a problem in Firefox 15 that is/will be fixed in firefox 16: https://bugzilla.mozilla.org/show_bug.cgi?id=789018
Firefox 15 is doing a speculative connect which is fine with HTTP/SPDY but because the WebSocket handshake is HTTP 1.0 (rather than 1.1) it is not able to re-use the speculative connection and has to make a second connection.
It's not a critical issue if your server is properly multithreaded and can accept multiple connections but it is annoying.

how can make two clients chat with each other?

this is not my homework(my homework is just about doing chat with a client and server which it works correctly especially with your help[:-)]
but I want to make two clients chat with each other,I don't know that when i get text from the first one how can I send that text to the other client.would you please help me.thanks.
public class MainServer {
static Socket client = null;
static ServerSocket server = null;
public static void main(String[] args) {
System.out.println("Server is starting...");
System.out.println("Server is listening...");
try {
server = new ServerSocket(5050);
} catch (IOException ex) {
System.out.println("Could not listen on port 5050");
System.exit(-1);
}
try {
boolean done = false;
while (!done) {
client = server.accept();
System.out.println("Client Connected...");
BufferedReader streamIn = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter streamOut = new PrintWriter(client.getOutputStream(),true);
String line = streamIn.readLine();
if (line.equalsIgnoreCase("bye")) {
streamIn.close();
client.close();
server.close();
done = true;
} else {
System.out.println(line);
streamOut.println(line);
}
}
} catch (IOException e) {
System.out.println("IO Error in streams " + e);
}
}}
That's it, your two "clients" will both act as client and server :
Listening to incoming things on a socket and sending things over an other sockets.
On the server, you can keep a Set of all the clients that are currently connected to the server. The server should listen for messages (can do this with a ServerSocket, and clients connect with normal Sockets). Each time the server receives a message, it sends this message back to all clients in the Set, and the clients display the message.
EDIT: this is for a client-server system, where clients connect to a central server instead of directly to each other. If you want to do direct client-to-client, one of them will just have to act as the server, and you'll need to implement a chat UI in both.
Here is a very simple, ~100 line, GUI chat program.
Have a look at Building an Internet chat system.
This explains how to write simple Clients and a Server with Java.
Unless you want to get into really complicated P2P discovery protocols, you would have to have a server to act at least as an intermediary.
In order to establish a direct client to client connection, the clients would need to know each others IP addresses. To do this, each client would first connect and "register" itself with a central server.
When a client wants to talk to another client, it would ask for that client's address from the server, then establish a connection directly with that client. So each client is acting both as a client (establishing connections with the server and other clients) and as a server (accepting connections from other clients).
It seems simple in theory, but in practice it gets more complicated. For example, what if the client you want to connect to is behind a firewall? You could have a hole in the firewall for incoming connections to get through, or you could fall back to having the communication go through the server, or if one of the clients is behind a firewall and the other isn't, the server could mediate the connection in the opposite direction.
Basically, there are two approaches:
One Chat server that receives all messages and distributes/forwards them to the clients (xmpp/jabber works this way)
One server that connects clients directly. Like on peer-to-peer networks
Looking back at your previous work, I think, the first approach is more feasible.
The server will offer one port where new clients can connect. After a client requests to participate/use the server, there server spawns a worker thread with a server socket on a different (available) port number and tell the client that port number. This is the reserved communication channel for that client with the server.
The rest is pretty straightforward: a client can send a new chat message, the server will pick it up and send it to all connected clients.
If a client disconnects, the worker thread will close the socket, return it to the pool and terminate.

Categories