Android socket connection errror : connect failed: ETIMEDOUT - java

I am developing an android app, that will be communicating with an wifi controler (fixed IP and PORT) using TCP , but since i don't have the controller yet. So i created a simple C# server programm that would recieve some test messages.
But when i try to open the connection in android, it gives me the Exception:
java.net.ConnectException: failed to connect to /10.0.2.2 (port 1234): connect failed: ETIMEDOUT (Connection timed out)
C# Program:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace Server
{
class Program
{
static byte[] Buffer { get; set; }
static Socket sck;
static void Main(string[] args)
{
sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sck.Bind(new IPEndPoint(0, 1234));
sck.Listen(100);
Socket accepted = sck.Accept();
Buffer = new byte[accepted.SendBufferSize];
int bytesRead = accepted.Receive(Buffer);
byte[] formatted = new byte[bytesRead];
for (int i = 0; i < bytesRead; i++)
{
formatted[i] = Buffer[i];
}
string strData = Encoding.ASCII.GetString(formatted);
Console.Write(strData + "\r\n");
Console.Read();
sck.Close();
accepted.Close();
}
}
}
Android code:
try
{
if (socket == null) {
int SERVERPORT = 1234;
InetAddress serverAddr = InetAddress.getByName("10.0.2.2");
socket = new Socket(serverAddr, SERVERPORT); // FAILS
}
}
} catch (IOException e) {
e.printStackTrace();
}
Its the first time i had to work with sockets. And i am DUMB when it comes to networking things. So it probably is a simple error.
Of course i checked all the related questions with this error, but still couldnt figure this out.
I am using GenyMotion Emulator.
Using Windows 8.1 64x.
I set the firewall settings to allow the C# app to communicate throgh windows firewall (public and private).
Does anyone know the solution? Thanks

Related

Android and Java Socket don't have the same behavior

I'm using Java to implement some socket programs.
I found that both of Android and Java have java.net.Socket, but the source code are not the same, so that they have different behavior.
I have a server(maybe PC or Android), and the server has multiple network interface(E.g. Ethernet, Wireless, USB or Bluetooth). The client will try to connect all the server network interface at the same time(one connection one thread). Until the client finds an available connection, they will communicate via the connection. In this way, I expect that the connection speed will not too low.
But when the client is trying to connect to server, it may encounter a repeat-connect situation in Android device(Android SDK). If the program encounter the repeat-connect situation, the previous connection will be reset or be replaced(I'm not sure) by the latter connection. At the same time, when reading or writing the previous connection, it will throw java.net.SocketException: recvfrom failed: ECONNRESET (Connection reset by peer). In the other hand, when reading or writing the latter connection, it is normal, but the connection speed is not very fast.
This problem seems to not be happened on PC but happened on Android when the client is trying to connect to server.
How can I solve it?
EDIT
The client code as below:
private Socket socket;
private IP ip;
private IP[] IPs;
private boolean closing;
private int socketTriedCount;
...
socketTriedCount = 0;
for (final IP ipObj : IPs) {
if (closing) {
break;
}
new Thread() {
#Override
public void run() {
try {
if (socket == null) {
final Socket s = new Socket();
s.connect(new InetSocketAddress(InetAddress.getByName(ipObj.getIP()), ipObj.getPort()), timeout);
synchronized (Client.this) {
if (socket != null) {
//Should not be happened
//s.close();
socketTriedCount++;
} else {
ip = ipObj;
socket = s;
socketTriedCount++;
}
}
}
} catch (final Exception ioE) {
socketTriedCount++;
}
}
}.start();
}

Java application getting different IP from android application - Why?

I made one android application that needs to connect one local database provided by wamp server. First using the android virtual device (AVD) my IP to connect the server first time used to be: 10.0.2.2. My AVD was connecting fine, but when I tried to connect direct on my device he wasn't finding the local server with this 10.0.2.2 IP. At this point I've changed IP to 192.168.1.5 which was my LAN cable IP, both device and AVD were running without problems... but sometimes I need to change my connection to wifi, which changes the IP..also, I realized that fix one IP in my source code will be a problem to release the android app, since other people will have other LAN IP address.
To solve this problem, I've started to look for a solution, such as acquire the LAN IP dynamically. For this purpose I built this Java application as test:
public class test {
public static void main(String[] args) throws Exception
{
String roundHost = null;
Enumeration<NetworkInterface> n = NetworkInterface.getNetworkInterfaces();
for (; n.hasMoreElements();)
{
NetworkInterface e = n.nextElement();
Enumeration<InetAddress> a = e.getInetAddresses();
for (; a.hasMoreElements();)
{
InetAddress addr = a.nextElement();
if (addr.isSiteLocalAddress()){
String pureHost = addr.getByName(addr.getHostName()).toString();
roundHost = addr.getHostAddress();
pureHost = pureHost.substring(addr.getHostName().length()+1);
if(!roundHost.equals(pureHost))
break;
}
}
}
System.out.println(roundHost);
}
}
As output, this java application gives me my correct LAN wifi IP or even my LAN cable IP which is 192.168.1.3 or 192.168.1.7. From here I made one "IPParser" to use on my android app:
public class IPParser {
String pureHost, roundHost = null;
public IPParser() throws UnknownHostException{
Enumeration<NetworkInterface> n = null;
try {
n = NetworkInterface.getNetworkInterfaces();
} catch (SocketException e1) {
e1.printStackTrace();
}
for (; n.hasMoreElements();)
{
NetworkInterface e = n.nextElement();
Enumeration<InetAddress> a = e.getInetAddresses();
for (; a.hasMoreElements();)
{
InetAddress addr = a.nextElement();
if (addr.isSiteLocalAddress()){
pureHost = addr.getByName(addr.getHostName()).toString();
roundHost = addr.getHostAddress();
pureHost = pureHost.substring(addr.getHostName().length()+1);
if(!roundHost.equals(pureHost))
break;
}
}
}
}
public String returnIp() {
return roundHost;
}
}
As you can see it's pretty similar; the difference is just some structural changes to adapt the needed syntax. And now comes the real problem: When I try to run this parser inside my AVD, my ip is 10.0.2.15 and running directly in my device the ip return is 192.168.1.6 - Obviously the android app is crashing because it can't find the local server to connect.
My IP config information:
I'm not an expert in network, so I ask, take it easy and if I said something technically wrong or adjacents please edit and correct me..finally I ask:
Why this is happening and what's possible to do to solve this problem?
The IPs you mention (10.0.2.2 and 192.168.1.5) are from two different networks, which makes sense since the documentation states that:
Each instance of the emulator runs behind a virtual router/firewall
service that isolates it from your development machine's network
interfaces and settings and from the internet. An emulated device can
not see your development machine or other emulator instances on the
network. Instead, it sees only that it is connected through Ethernet
to a router/firewall.
The virtual router for each instance manages the 10.0.2/24 network
address space — all addresses managed by the router are in the form of
10.0.2., where is a number. Addresses within this space are pre-allocated by the emulator/router as follows:
What this means is that when using the AVD there is a virtual network that is created which the device and the computer are part of. In your case your local machine takes the address 10.0.2.2 in this virtual network and the AVD 10.0.2.15. But when you connect directly through your device, the computer's IP (as well as the device's) is in the LAN's address space (i.e. 192.168.1.5 and 192.168.1.6).
The code you posted resolves the IP address of the host, but if you want the device to resolve automatically the server's IP address and you can guarantee they will always be both connected to the same LAN, then you can use multicast UDP messages (I didn't find a really good source but you can start here, here and here). This type of communication sends a UDP datagram to the network to a specific multicast IP address and port, to which other devices in the network are listening. I've used this scheme in an Android application that needed to find a computer in the network so I know for a fact that it works. I can share some code if you need to.
EDIT
The following snippets of code are the ones that implement the search of computers in the network. The Android application this was used in could control the mouse and keyboard of any computer in the network that had the server application running.
Android Client
public void findComputers(View v) {
try {
int port = 4444;
String multicastAddr = "224.168.1.0";
DatagramSocket socket = new DatagramSocket(port);
socket.setSoTimeout(300);
InetAddress group = InetAddress
.getByName(multicastAddr);
DatagramPacket packet = new DatagramPacket(new byte[] { 1 }, 1,
group, port);
socket.send(packet);
// Give time to the servers to respond
Thread.sleep(100);
while (true) {
try {
// Listen for the servers responses
byte[] buffer = new byte[256];
packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
String data = new String(packet.getData());
// Information sent from servers include the host's name
// and IP addres separated by a semicolon.
String[] parts = data.split(";");
// Add a server to the result list.
Computer computer = new Computer(parts[1].trim(),
parts[0].trim());
this.computers.put(computer.getName(), computer);
} catch (InterruptedIOException ex) {
break;
}
}
socket.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
String output = "No computers found.";
if (this.computers.size() > 0) {
output = this.computers.size() + " computer(s) found.";
this.fillComputers();
}
Toast.makeText(this, output, Toast.LENGTH_SHORT).show();
}
Server
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
/**
* Receives UDP broadcast packets in the default port requesting for server name
* and IP, broadcasting the information in return.
*
* #author jfacorro
*
*/
public class NameResolverService extends Thread {
private InetAddress localAddress = null;
private byte[] localAddressData = null;
private MulticastSocket socket = null;
private boolean exit = false;
public NameResolverService() {
}
public void exit() {
this.exit = true;
this.socket.close();
}
#Override
public void run() {
try {
int port = 4444;
String multicastAddr = "224.168.1.0";
// Get current address
this.localAddress = InetAddress.getLocalHost();
this.socket = new MulticastSocket(port);
InetAddress group = InetAddress.getByName(multicastAddr);
this.socket.joinGroup(group);
this.localAddressData = (this.localAddress.getHostAddress() + ";" + this.localAddress
.getHostName()).getBytes();
} catch (IOException ex) {
this.notified.notified(ex.getMessage());
ex.printStackTrace();
}
while (!this.exit) {
try {
byte[] buffer = new byte[1];
DatagramPacket packet = new DatagramPacket(buffer,
buffer.length);
socket.receive(packet);
InetAddress address = packet.getAddress();
int port = packet.getPort();
packet = new DatagramPacket(this.localAddressData,
this.localAddressData.length, address, port);
socket.send(packet);
} catch (IOException e) {
if(!this.exit)
e.printStackTrace();
}
}
this.socket.close();
}
}

Issue connecting a client to localhost using Java

I'm trying to setup a protected client and protected server connection using sockets. Whenever I run the program I receive a connection error saying the connection was refused. I'm using Java in Eclipse IDE running on MAC OS. Any ideas why this code cannot connect to my localhost?
Protected Client:
public static void main(String[] args) throws Exception
{
String host = "localhost";
int port = 7999;
String user = "George";
String password = "abc123";
Socket s = new Socket(host, port);
ProtectedClient client = new ProtectedClient();
client.sendAuthentication(user, password, s.getOutputStream());
s.close();
}
Protected Server
public static void main(String[] args) throws Exception
{
int port = 7999; //7999
ServerSocket s = new ServerSocket(port);
Socket client = s.accept();
ProtectedServer server = new ProtectedServer();
if (server.authenticate(client.getInputStream()))
System.out.println("Client logged in.");
else
System.out.println("Client failed to log in.");
s.close();
}
When I run the program I receive the following error:
Exception in thread "main" java.net.ConnectException: Connection refused
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:382)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:241)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:228)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:431)
at java.net.Socket.connect(Socket.java:527)
at java.net.Socket.connect(Socket.java:476)
at java.net.Socket.<init>(Socket.java:373)
at java.net.Socket.<init>(Socket.java:216)
at ProtectedClient.main(ProtectedClient.java:36)
I have gotten this error before when using particular sockets. Try a different socket like 5687. (Or if you need that particular socket, try making sure your firewall allows it).
Make sure you call client.close() on the server as well. If your program worked once it might be blocking that port.

Running Java EE application on web-server

Following is a thread which has a SOCKET listening at port 15445.
Whenever a Datagram packet is sent to it, it forwards back to the sender's address after adding a String(Reply from SERVER) in it. I want this code to run somewhere on the Internet, but I don't know where to start.
Is it possible? Can I run this code on a Tomcat server or do I need to do something different?
import java.io.*;
import java.net.*;
public class HelloWorld extends Thread {
protected DatagramSocket socket = null;
protected BufferedReader in = null;
public HelloWorld() throws IOException {
socket = new DatagramSocket(15445);
}
public void run() {
while (true) {
try {
byte[] buf = new byte[256];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
InetAddress address = packet.getAddress();
int port = packet.getPort();
String s = "Reply from SERVER";
byte[] b= s.getBytes();
packet = new DatagramPacket(b, b.length, address, port);
socket.send(packet);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws IOException {
new HelloWorld().start();
}
}
No, Tomcat isn't a web server. It's a servlet/JSP engine that happens to have an HTTP server built in.
This looks like POJO with a main. Why can't you just run that as a service? Why do you think you need a web server?
Use Jetty (echo server is one of the tutorials afaik) and expose your port to the internet.
If your code works fine forward the necessary port through your router so it's reachable from the internet. If your looking for a hosted solution, vservers are a cheap way to start. http://www.superuser.com is the place to go for network configuration.

client can not connect from another ip

I wrote a simple client-server application. It works very well on my computer. but when my friend tries to connect my server he can't. I create the server on my computer with port 23. Here is the part of creating the server:
public Server(int port_number) throws IOException{
create_Server(port_number);
}
public static void main(String[] args) throws IOException {
int port_number=23;
new Server(port_number);
}
private void create_Server(int port_number) throws IOException{
ss = new ServerSocket(port_number);
System.out.println("Server is ready!");
while(true){
s=ss.accept();
System.out.println(s.getLocalAddress().getHostName() + " was connected!");
send_con_mes();
list.put(s,new DataOutputStream(s.getOutputStream()) );
new ServerThread(s,this).start();
}
}
and here is the client part ;
public void start_Chat() {
try {
Ip_addr = JOptionPane.showInputDialog("Enter the IP number of the server to connect : ");
s = new Socket(Ip_addr, 23);
Client_name = JOptionPane.showInputDialog("Enter your Nickname : ");
dis = new DataInputStream(s.getInputStream());
dos = new DataOutputStream(s.getOutputStream());
new Thread(Client.this).start();
well I can talk, send private messages etc. When I connect to server on my computer as clients, but the final problem is a client from another IP cannot get connected.
You have to configure your network to allow this port to be accessed. This means enabling firewall on you PC, and your routers etc. There is nothing you can do in Java to avoid having to get this right first.
EDIT: If the other machine is trying to connect to you via an Internet router they will have to use your public IP address rather than your internal PC address. If you don't know your public address you can use a site like http://whatismyipaddress.com/. Unless you have a static IP address it can change when you reconnect. (One reason to stay connected all the time)

Categories

Resources