I'm trying to connect a client android to a app server java, but no work. This is code:
Android client;
_cb_led1.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
Socket mySocket = new Socket("127.0.0.1", 9090);
PrintStream p = new PrintStream(mySocket.getOutputStream());
p.println("Mensaje");
}
});
Java Server:
s = new ServerSocket(9090);
sc = s.accept();
System.out.println("Conexión establecida");
b = new BufferedReader( new InputStreamReader ( sc.getInputStream() ) );
while ( true )
{
mensaje = b.readLine();
System.out.println(mensaje);
}
b.close();
sc.close();
s.close();
}
catch (IOException e)
{
System.out.println("No puedo crear el socket");
}
}
any suggestions
thank you very much
127.0.0.1 points to localhost on the emulator. You have to either use the actual ip address of your computer or 10.0.2.2 which points to localhost on the computer running the emulator.
127.0.0.1 means "this machine". Is the server really on the same Android device (or emulator)?
If it is, why bother with socket connections? If it's not, please specify a real address or name.
From the standpoint of the Android emulator, the computer it's hosted on is not the same machine. If that's where the server is running, use its publicly available IP address.
Related
Android especially.
I will try to establish a connection between two devices (android - android) where one will create a server socket, connect the other device to the client, close the socket, and the connection between the two devices remains. So simple.
Server
#Override
public void onResume() {
super.onResume();
//// !!! only for test !!!
(new Thread(new Runnable() {
#Override
public void run() {
try {
int port = 33000;
SocketAddress allInterfaces = new InetSocketAddress("0.0.0.0", port);
ServerSocketChannel channel = MuxServerSocketChannelFactory
.openAndBindServerSocketChannel(null, allInterfaces, 3);
ServerSocket server = channel.socket();
Socket socket = server.accept();
Log.i("test", "host was connected!!!: " + socket.getInetAddress().getHostAddress());
callback.onConnected(socket);
server.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
})).start();
if (true) return;
//// !!! end test on real device !!!
}
Client
int privateServerPort = 33000;
int publicServerPort = 25000;
InetAddress privateServerIpAddr = InetAddress.getByName("172.23.9.120");
InetAddress publicServerIpAddr = InetAddress.getByName("xx.xx.xx.xx"); // correct IP address
Socket socket = new Socket(publicServerIpAddr, publicServerPort,
privateServerIpAddr, privateServerPort);
// never connected
The problem arises when these devices are not in one LAN or in one, but via a VPN. It is not possible to create this connection at this time.
I've been looking for a long time here (Stackoverflow), but it does not work for me. Some of the Libraries I tried:
Portmapper
// Discover port forwarding devices and take the first one found
List<PortMapper> mappers = PortMapperFactory.discover(networkBus, processBus);
PortMapper mapper = mappers.get(0);
// mappers always return null
Cling
final PortMapping desMapp = new PortMapping(
33000,
Tool.getLocalHost(false).getHostAddress(),
PortMapping.Protocol.TCP
);
UpnpService service = new UpnpServiceImpl(new AndroidUpnpServiceConfiguration());
RegistryListener registryListener = new PortMappingListener(desMapp) {
#Override
public synchronized void deviceAdded(Registry registry, Device device) {
super.deviceAdded(registry, device);
// this callback is never call
}
};
service.getRegistry().addListener(registryListener);
Collection<Device> all = service.getControlPoint().getRegistry().getDevices();
// the value all has 0 size
service.getControlPoint().search();
Thread.sleep(5000); // anything value
all = service.getControlPoint().getRegistry().getDevices();
// again the size is 0
Is there a really simple example of How the server and client should look?
All IP addresses and ports i know. I'm testing it on Huawei P9 Lite, Elephone P9000.
I do not work with UPnP, NAT and so on.
Thank you very much for your help.
I'm trying to build a basic client-server application.
When I run both the server and the client on the same computer both manage to connect without a hitch but if I try to do so from different computers (desktop and laptop) the connection doesn't get though. The server isn't even aware that someone tried to connect to it while the client timeouts after a while. At first I assumed that it's a firewall problem but disabling the firewall completely on the server PC did not help. Tried changing ports and checked on multiple computers. Any ideas what could cause this?
I control both the server and the client and can change the code of both if necessary. The server always runs on the same PC and I'm connecting to it directly using hardcoded IP address.
This is the code of the client sending random int to the server.
public static void main(String[] args) {
Socket s = new Socket();
try {
s.connect(new InetSocketAddress("123.45.67.891", 8084), 5000);
s.getOutputStream().write(42);
s.close();
} catch (IOException e) {
e.printStackTrace();
return;
}
}
The server is slightly more complicated but considering the fact that they manage to connect while being run from the same PC I assume that the problem isn't with it.
edit: Server code (Thread per client. There shouldn't be too many of those)
public void run() {
try {
serverSocket = new ServerSocket(listenPort); //integer
} catch (IOException e) { ... }
while (shouldRun) {
try {
Socket clientSocket = serverSocket.accept(); // Blocked here while trying to connect from remote computer
//Never gets here
ConnectionHandler newConnection = connectionHandlerCreator.create(clientSocket);
connectionHandlers.add(newConnection);
newConnection.initialize();
new Thread(newConnection).start();
} catch (IOException e) { ... }
}
}
Initialize consists of the following (which latter used for I/O).
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out = new PrintWriter(clientSocket.getOutputStream(), true);
The problem is probably on your server side though: you have to make it respond to all ip's not just local one, by using the constructor:
ServerSocket(int port)
it will default accepting connections on any addresses which is not the case if you specified an IP
I have problem to connect my android client to my PC Server
here there are the codes
-->PC SERVER:
public class Server {
public static void main(String[] args) throws IOException, SQLException, ClassNotFoundException
{
ServerSocket server = new ServerSocket(4444);
System.out.println("Waiting for clients to connect...");
while (true)
{
Socket s = server.accept();
InetAddress clientAddress = s.getInetAddress();
System.out.println("Incoming connection from: " + clientAddress.getHostName() + "[" + clientAddress.getHostAddress() + "]");
s.close();
}
}
}
--->ANDROID CLIENT:
public class Main extends Activity {
Button b;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b = (Button)findViewById(R.id.connect);
b.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View arg0) {
try {
Socket client = new Socket("10.0.2.2", 4444); //connect to server
client.close(); //closing the connection
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
When on my android device i click the button in my server program(PC) doesn't view device connect...why? i've tried to insert
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
into my AndroidManifest but when i click on button program crash
Android device and PC are connected to same network(router DSL).
Help me please
10.0.2.2 is an address that is used by your app running in an emulator to connect with a server running on your pc. The emulator is on the same pc. If you use a real devive you have to use the (W)LAN address of your pc which is in the same WLAN as your device. Often something like 192.168.0.12. Find out with ipconfig.
The address you are using is 10.0.2.2, which is non routable as private.
You should use an address that your device can resolve. Either a DNS name published in a DNS accessible from your phone (so a public one) or a routable IP. Your server should be reachable from the public network, which is unlikely to be the case of your PC unless you have specifically took care of that - I am not sure of what you mean by this:
Android device and PC are connected to same network(router DSL)
Please have a look at the exception that is thrown on phone side and edit your post with the resulting stack trace. It will help to dig into this further.
Your socket declaration should be as follow :
Socket client = new Socket(10.0.2.2, 4444); //Quotes removed
I have searched everywhere to find an answer for this question:
I have a TCP client on my android application that sends an message to the server which is written in Visual Basic .NET Framework 4.
Now i want to send an message from my server to the phone over 3g, it works on wifi and 3g..
private class startserver extends Thread
{
public void server() throws Exception
{
String clientSentence;
String capitalizedSentence;
ServerSocket welcomeSocket = new ServerSocket(8765);
while(true)
{
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient =
new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
System.out.println(clientSentence.substring(1));
msgshower = clientSentence.substring(1);
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(MainActivity.this, "Received: " + msgshower , Toast.LENGTH_LONG).show();
}
});
capitalizedSentence = clientSentence.toUpperCase() + '\n';
outToClient.writeBytes(capitalizedSentence);
}
}
#Override
public void run() {
try {
server();
} catch (Exception e) {
e.printStackTrace();
}
}
I start it in the OnCreate method
Now i send a message with (VB.NET)
Private Sub sends(ByVal message As String)
Dim tcp As New TcpClient
tcp.Connect(connectedIP, 8765)
Dim bw As New IO.BinaryWriter(tcp.GetStream)
bw.Write(message)
bw.Close()
tcp.Close()
End Sub
On wifi it will arrive, on 3g it wont... any idea's how to do this?
How do other applications archive this?
I think you're having problem with the ip address asigned by your mobile phone operator. The fact that works on wifi, but not on 3G, I think that is because your mobile(when connected through 3G) doesn't have a public IP address.
When you use SocketServer in your mobile, you're opening a port a waiting for others to connect to it. If your IP address is not reachable from internet, it won't happen (it's like having a computer behind a firewall.)
Could you try to implement the server in the VB machine, assuming that it has a public reachable address? This way, the phone wouldn't act as a server, it wouldn't be necessary to have a reachable address, as long as the VB machine has one. Then, you should use Socket class to bind to the server ip and port.
Totally confused by your code list above..
If you want to host a server in VB.NET, you should not use TcpClient class but TcpListener and if you need a better performance, use Socket class directly.
At the Android client side, you should new Socket(server,servPort), when you want to send message, write the outputStream, and read the inputStream to receive message.
It appears to me that newer Android devices run behind a NAT, where the local address is an internal carrier or LAN address and the public address is the router or carrier assigned external address.
Nevertheless, newer phones don't return the same address using the NetworkInterface as when accessing an IP detection service.
Therefore, connecting via direct P2P SocketChannels inherently fails.
Are there any common workarounds to this problem designed for the Android platform? Can anyone clarify what is causing this NAT-like security issue?
Any links to Java NAT traversal tutorials or examples (NOT essays or theses) would also be appreciated as being helpful (as I'm not quite sure how to implement it in Java).
I will of course also accept any other solutions anyone has to offer!
Almost every phone or PC you will ever touch won't have a static public IP address, and therefore will require NAT traversal. It's not because of the device; the carrier or ISP put routers between your device and the public internet. Depending on your application, usually there are NAT-traversal libraries you can use, such as ice4j or STUNT.
I do that in my own project and have found this issue is not that complicated.
Here's a very simple UDP echo server in node.js
var dgram = require('dgram');
var socket =
dgram.createSocket('udp4');
socket
.on('listening', function()
{
var address = socket.address();
console.log('socket listening ' +
address.address + ':' + address.port);
})
.on('error', function(err)
{
console.log('socket error:\n' + err.stack);
socket.close();
})
.on('message', function(message, rinfo)
{
console.log('message: ' + message + ' from ' +
rinfo.address + ':' + rinfo.port);
var msg = new Buffer(rinfo.address + ':' + rinfo.port);
socket
.send(msg, 0, msg.length,
rinfo.port, rinfo.address,
function(err, bytes)
{
//socket.close();
});
})
.bind(15000);
An android client simply send a msg to this node server
System.out.println("UDP hole punching=======================");
class IOth extends Thread {
#Override
public void run() {
String sendMsg = "UDP hole punching";
byte[] buf = sendMsg.getBytes();
DatagramPacket packet;
System.out.println(HPremoteHost); // node server IP
System.out.println(HPremotePort); // 15000
try {
packet = new DatagramPacket(buf, buf.length, InetAddress.getByName(HPremoteHost), HPremotePort);
ds.send(packet);
} catch (Exception e) {
System.out.println("error================");
System.out.println(e);
}
}
}
IOth io00 = new IOth();
io00.start();
Android Client UDP listener to obtain general msg and your own Global ip&port via UDPholepunching
class IOLoop extends Thread {
#Override
public void run() {
try {
String msg = "Native.UDPserver.open";
SocketAddress sockAddress;
String address;
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
while (true) {
try {
ds.receive(packet);
sockAddress = packet.getSocketAddress();
address = sockAddress.toString();
msg = new String(buf, 0, packet.getLength());
System.out.println(msg + " received !!! by " + address);
// this case is UDP HolePunching reaction
if (address.equals(HPaddress1)) {
System.out.println(msg + "hole punched");
// So you can obtain own Global ip& port here.
// exchange this information
// `remoteHost` `remotePort` to another client
// with some method (signaling server)
}
} catch (IOException e) {
}
}
} catch (Exception e) {
}
}
}
IOLoop io00 = new IOLoop();
io00.start();
Android Client UDP sender using other client's IP remoteHost remotePort
class IOth extends Thread {
#Override
public void run() {
String sendMsg = "This is a test message";
byte[] buf = sendMsg.getBytes();
DatagramPacket packet;
try {
packet = new DatagramPacket(buf, buf.length, InetAddress.getByName(remoteHost), remotePort);
ds.send(packet);
} catch (Exception e) {
}
}
}
IOth io00 = new IOth();
io00.start();
Look at http://sourceforge.net/projects/jnat-pmplib/
It is an implementation of NAT-PMP in java.
I've managed to establish sockets just by forwarding the sockets you're using during the connection in your router. It worked for me.
UPDATE
Find out your IP address through cmd.exe if your using Windows (ipconfig) or through a terminal session if your on Linux (ifconfig). Then connect to it through the browser and there should be a security section. Go to port forwarding and open up the ports your using when establishing you're ServerSocket and Socket. Use TCP as the protocol.
Please note that this only applies if you're trying to connect from outside your wlan.