Good day,
I have a java game that I want to play with a friend over network, I have implemented Sockets and tested the game on my pc using localhost as address, but was unable to connect to the external ip of my pal's pc, presumably due to us both being behind routers.
Here is the code of host/client:
CLIENT:
try {
socket = new Socket(inputHostIp(), 5555);
} catch (IOException e) {
e.printStackTrace();
}
SERVER:
try {
hostServer = new ServerSocket(5555);
} catch (IOException e1) {
e1.printStackTrace();
}
listenForUserConnection();
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
Socket socket = null;
try {
socket = hostServer.accept();
} catch (IOException e) {
e.printStackTrace();
continue;
}
joined(socket);
}
The exception I am getting now is
java.net.ConnectException: Connection timed out: connect
On trying to init I/O:
java.net.SocketException: Socket is not connected
java.net.Socket.getInputStream/java.net.Socket.getOutputStream
I have set up port forwarding with the chosen port number (5555) linked to the internal ip on both our machines.
What are my options for getting this to work?
ADDENDUM:
We have also tried using Hamachi to create a virtual LAN, but there seems to be an issue with that - we can’t ping one another even through that, it diagnoses with an issue -
Tunnel:
VPN domain's tap device is down
Local results:
Adapter configuration:
Cannot get adapter config
Traffic test: Cannot complete test
Peer results: [160-056-951]
Adapter configuration: OK
Traffic test: Inbound traffic blocked, check firewall settings
I have tried shutting down firewalls, hamachi issues changed to just ‘cannot get adapter config’, but otherwise no results.
On my pc, however, I got a version of windows that doesn’t seem to display Firewall setting properly, if you think it’s likely an issue, can you tip me on how to test my firewall?
Related
My problem is: I need to discovery if one IP and Port is running a SMTP service.
To do this, I'm using SMTPClient to try open a connection. I'm using the code below.
private static boolean validateSMTP(String ip, int port, int timeOut) {
SMTPClient smtp = new SMTPClient();
try {
smtp.setConnectTimeout(timeOut);
smtp.connect(ip, port);
return true;
} catch (SocketException e) {
LogAplication.Warning("Ops... something wrong", e);
} catch (IOException e) {
LogAplication.Warning("Ops... something wrong", e);
}
finally{
smtp = null;
}
return false;
}
It's working fine and I've gotten the expected results, but the timeOut has been my problem.
E.g: If I try ip: 127.0.0.1 and port 80 (IIS open port) the connect step takes a long (much more than is defined in timeout) to throw an exception
java.net.SocketException: Connection reset
How can I set timeOut for this case? Or existis another way to do my simple test ?
After take a look at grepCode, I found this for method connect(string host, int port):
Opens a Socket connected to a remote host at the specified port and
originating from the specified local address and port. Before
returning, _connect Action() is called to perform connection
initialization actions.
As the port is opened by another service, the socket is opened, not causing timeOut (by socket), but the exception was thrown by "connectAction()"
So I needed to set a global timeOut for my SMTPClient, which is used by socket connection and inside of "connectAction()" . And I did this to solve my problem:
smtp.setDefaultTimeout(timeOut);
With this, now I've the expected results for, open ports which throws exceptions and of course, the successfully connection for SMTP services.
I'm writing an Android app to communicate with a Windows service over socket connections.
The code is working but I want to add the ability to detect devices connected on local network so the app can determine which computer is running the windows service I want, I'm using the code below which I got from this website too. My issue is the code below only detects android devices and doesn't detect my laptop. I can ping my device from my laptop and ping my laptop from my device, so what to do from here?
public void checkHosts(String subnet) {
int timeout = 1000;
for (int i = 1; i < 254; i++) {
String host = subnet + "." + i;
try {
if (InetAddress.getByName(host).isReachable(timeout)) {
System.out.println(host + " is reachable");
System.out.println("Host Name: "
+ InetAddress.getByName(host).getHostName());
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
InetAddress.isReachable() is not very reliable.
If ICMP messages are blocked you won't get an answer.
What you could do is sending a broadcast message.
Your server application has to listen for this message and answer it.
This way you get the server IP address and you can connect to it.
And you have to send only one message to reach all hosts in the subnet.
Example code for sending and receiving broadcast messages
Thank you everyone I ended up creating a socket connection to each IP in the network and displaying host name from the socket. it showed me all devices whether they are android devices or windows machines.
Of course since I made the socket listen at port 8000 on both device and computer, so using a socket will give result IF AND ONLY IF both ends are listening on the same port, and I only care about computers that are running my service.
I really appreciate all the suggestions and help :)
I am using Java to do the socket programming as below.
Client program is as below:
Socket MyClient;
try {
MyClient = new Socket("Machine name", PortNumber);
}
catch (IOException e) {
System.out.println(e);
}
Server program is as below:
ServerSocket MyService;
try {
MyServerice = new ServerSocket(PortNumber);
}
catch (IOException e) {
System.out.println(e);
}
Socket clientSocket = null;
try {
clientSocket = MyService.accept();
}
catch (IOException e) {
System.out.println(e);
}
Now my question is if I run more than one thread to open several sockets in one port (as the server code above), how my client program know which socket it is connecting to?
Your client connects to the Servers port. So all clients will be having the same code
MyClient = new Socket("Machine name", <port where server is listening>);The port opened at client side is not important. The client will get a free port available in his OS.
how my client program know which socket it is connecting to?
The question doesn't make sense. It doesn't 'connect to a socket' at all, it connects to a listening port, and there is only one of those. Your server only accepts one client, so the second and subsequent threads will get an undefined behaviour ranging from a ConnectException to a ConnectionException to nothing, most probably the latter.
Your application knows it because you set it up with a specific port. There is no "auto discovery" built into TCP/IP, it's up to you to pick a server-port and make sure you set your clients up to connect to that port. Either you hard-code this into your client application or, better yet, have it in some configuration file you include with the client.
This is why you have a bunch of "known ports", like http is port 80. This means that a browser will always connect to port 80 on a web-server, unless you explicitly indicate another port in the URL.
I am using the following java code in Android AVD on Windows7 to create my server with serverPort = 1131;
try {
ServerSocket serverSocket = new ServerSocket(serverPort);
serverSocket.setReuseAddress(true);
while(isRunning){
try {
final Socket socket = serverSocket.accept();
DefaultHttpServerConnection serverConnection = new DefaultHttpServerConnection();
serverConnection.bind(socket, new BasicHttpParams());
httpService.handleRequest(serverConnection, httpContext);
serverConnection.shutdown();
} catch (IOException e) {
e.printStackTrace();
} catch (HttpException e) {
e.printStackTrace();
}
}
serverSocket.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
I get the following exception :-
01-18 06:30:03.381: W/System.err(1494): java.net.BindException: bind failed: EACCES (Permission denied)
The firewall on my machine is off & I have added special rules for that as well.
Do I need to do something special for running server on AVD on Window7?
Kindly help.
Thanks
I found the following on the MSDN site (search the site for "bind" and "EACCES"):
WSAEACCES - 10013
Permission denied.
An attempt was made to access a socket in a way forbidden by its access permissions. An example is using a broadcast address for sendto
without broadcast permission being set using setsockopt(SO_BROADCAST).
Another possible reason for the WSAEACCES error is that when the bind function is called (on Windows NT 4.0 with SP4 and later),
another application, service, or kernel mode driver is bound to the
same address with exclusive access. Such exclusive access is a new
feature of Windows NT 4.0 with SP4 and later, and is implemented by
using the SO_EXCLUSIVEADDRUSE option.
Thus, if we assume that the JVM native libraries map WSAEACCES to this exception, there are two obvious possible explanations:
This is a permissions-based thing. ADV doesn't have permission to bind to that port.
Some other application has already bound to the port with the SO_EXCLUSIVEADDRUSE socket option.
IMO, either explanation is plausible. (Or it could be something else ...)
I'm trying to connect to a simple Java server on my computer (in the future a true server, but I'm just learning how to program with sockets first. When I try to connect, the application on the phone throws an IOException. However, on the emulator, it does NOT.
I do have:
< uses-permission android:name="android.permission.INTERNET"/>
included in the manifest. And here's the code block that's executed when I hit open:
try {
responseField.setText("Opening socket...");
Socket socket = new Socket(getIP(),Integer.parseInt(getPort()));
responseField.setText("Socket opened. Initializing out...");
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
responseField.setText("Done. Initializing in...");
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
responseField.setText("Done.");
} catch (NumberFormatException e1) {
responseField.setText("NumberFormatException");
} catch (UnknownHostException e1) {
responseField.setText("UnknownHostException");
} catch (IOException e1) {
responseField.setText("IOException");
}
Are you making sure that the server end uses a ServerSocket and uses the ServerSocker.accept() method?
So it seems that a weak Wi-Fi signal is causing error. I tried to surf the web (Google, CNN, etc.) afterward, and I could not. So I will just have to test on the emulator for now, or in a stronger signal. Thanks
If you were able to connect to the web before (I am assuming) but not after, then its not a problem with the wifi strength. Also depending on place you are surfing, the wifi router may have been configured not to allow such connections. Try to ping your server IP using a different computer within the same network and see whether you can ping. Emulator will work since the server is running on the localhost.