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.
Related
I'm trying to set up a simple test FTPS server in Java using Apache FtpServer and connect to it using a domain name instead of the IP address.
I've pointed the A record to the IP address and set up the SSL certificate. Based on the Apache FtpServer documentation, here is what my code looks like so far:
FtpServerFactory ftpServerFactory = new FtpServerFactory();
ListenerFactory listenerFactory = new ListenerFactory();
listenerFactory.setPort(990);
listenerFactory.setServerAddress("example.com");
SslConfigurationFactory sslConfigurationFactory = new SslConfigurationFactory();
sslConfigurationFactory.setKeystoreFile(JKS);
sslConfigurationFactory.setKeystorePassword(JKS_PASS);
listenerFactory.setSslConfiguration(sslConfigurationFactory.createSslConfiguration());
listenerFactory.setImplicitSsl(true);
ftpServerFactory.addListener("default", listenerFactory.createListener());
PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();
userManagerFactory.setFile(USERS_PATH.toFile());
BaseUser test = new BaseUser();
sample1.setName("test");
sample1.setPassword("test");
sample1.setHomeDirectory(HOME.getAbsolutePath().toString());
test.setAuthorities(List.of(new WritePermission());
UserManager userManager = userManagerFactory.createUserManager();
try {
userManager.save(test);
}
catch (FtpException e) {
e.printStackTrace();
}
ftpServerFactory.setUserManager(userManager);
FtpServer server = ftpServerFactory.createServer();
try {
server.start();
}
catch (FtpException e) {
e.printStackTrace();
}
However, when I try to connect to the FTPS server, I get an ECONNREFUSED - Connection refused by server from my FTPS client.
Are there any steps that I missed?
If your client reports a 'connection refused' that usually indicates (no guarantee) that no firewall prevented the TCP traffic, the connection request ended up on the intended machine but nothing was accepting the connection on the port you tried to connect to.
Things you can check:
Was the server process running? Was the server process on the correct port? Did the client connect to the correct port?
You might try to connect with another client (e.g. curl) just to see whether the TCP connection can be established.
You might try to connect to another port (e.g. 22 / ssh) to see if the client can establish the connection.
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.
In my desktop application, I am connecting to a server through a web service.
Using the code below getting the client machine Tomcat status, I can get the server IP address and port number, but how can I find the server Tomcat status?
InetAddress locIP = InetAddress.getByName("127.0.0.1");
serverSocket = new ServerSocket(8080, 0, locIP);
You can use Java's URLConnection as follows:
try {
URL url = new URL("http://youserver.com");
URLConnection urlConnection = url.openConnection();
urlConnection.setConnectTimeout(2000); //Connection timeout
urlConnection.connect();
System.out.println("Server is up and running");
} catch (Exception e) {
System.out.println("Server is not yet up");
}
if urlConnection.connect()returns silently within 2 seconds, means the server is up and running, else an exception is thrown which indicates the server is not up or the URL is incorrect.
All you need to do to detect a running Tomcat here or elsewhere is to try to connect to it with a new Socket(). If that works, it's running; if not, not. Don't send anything, just close the socket immediately.
I developed a chat application Java/Socket(TCP), it works perfectly on my local network,however when i put it behind a router it does not work...
I have already tested the open ports on my router at:
http://www.yougetsignal.com/tools/open-ports/
the result is as follows
80 (HTTP)is open
21 (FTP)is open
22 (SSH)22 is open
23 (TELNET)is open
25 (SMTP)25 is open
.
.
.
I started my server with this list of ports(java -jar server.jar 23) :
int port=Integer.parseInt(args[0]);
ServerSocket serverSocket = null;
serverSocket = new ServerSocket(port);
System.out.println("server started at " + port);
Socket clientSocket = null ;
// repeatedly wait for connections, and process
while (true) {
try {
clientSocket = serverSocket.accept();
} catch (IOException ex) {
System.out.Println("error");
}
System.err.println("new client connected!");
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream())),true);
String s;
while ((s = in.readLine()) != null) {
out.println("from server: "+s);
}
// colse all
out.close();
in.close();
clientSocket.close();
then Then with a simple client I tried to connect => anything received....
where does the problem? so how Skype,Msn and others chat application works fine?
there is a solution to do that ?
PS:I put a simple code(echo server) that represents my real server so you understand my code quickly :).
My regards .
This is just a guess, did you go into your router's configuration utility and set it up to proxy (usually called port forwarding) telnet requests to the client? Your router may be listening on 23, but unless you're running the chat client on the router's firmware, I doubt it knows what to do with that traffic. Maybe I misunderstood your question though.
Just having a server running behind a router is not enough for an outside client to establish a connection. Whatever port the server is listening on, the router needs to have a Port Forwarding rule configured on it that forwards inbound traffic for that port to the machine the server is running on. The client then needs to connect to the port on the router's public IP so the router can then forward that traffic to the server.
I'm getting following error when my client tries to connect to my server socket:
java.net.ConnectException: Connection refused: connect
But, my server is really running, on the same machine. I try to connect to it by using the external IP of my router. But when I try to connect with "localhost", it works. And, yes I did port forwarding correcly in my router. Even canyouseeme.org can connect to my server (The site says: "success" and in my server-log appears that someone connected with the server.)
So, is it for one or another reason impossible to connect to the same machine (or to a machine in the same network) via an external IP? Or is this something typical for Windows? (Normally, I use Linux)
I also tried to completely disable Windows Firewall.
ServerSocket:
public ServerSocket ssocket;
public List<ClientHandler> handlers;
public Server(int port) { // Constructor
try {
ssocket = new ServerSocket(port);
this.handlers = new ArrayList<ClientHandler>();
IpSharingManager.uploadData(Utilities.getPublicIp(), port);
} catch (Exception e) {
e.printStackTrace();
System.exit(-1);
}
}
Client:
public InvisibleClient(String host, int port) {
try {
System.out.println("Trying to connect to " + host + ":" + port);
this.host = host;
this.socket = new Socket(host, port);
this.bis = new BufferedInputStream(this.socket.getInputStream());
this.bos = new BufferedOutputStream(this.socket.getOutputStream());
this.console = new RemoteConsole(this.socket);
initializeCommunication();
System.out.println("Successfully connected!");
new Thread(this, "Client Thread").start();
} catch (Exception e) {
e.printStackTrace();
System.out.println("No server available");
}
}
Thanks
Some routers doesn't allow the internal network to connect to the external IP address of the router.
You can try to use telnet to connect to your server socket. If telnet isn't able to establish a connection, it's likely a networking problem.
Add the java.exe process and the port to your firewall exception list?
edit: Just read you already tried that. All I can suggest is make sure the network is not blocking that port. (routers)
Have You tried running it with JVM option: java.net.preferIPv4Stack=true ?
For what I see in your code, you missed the part where you accept the conection, after instantiating the server socket you need ssocket.accept() to accept conections and then you have to start reading the outputstrem from the socket