socket - Android conéctese al zócalo de anclaje
socket io para android (3)
Tengo 2 dispositivos Android, uno actúa como servidor que está en modo tethering y acepta conexiones a un puerto. El otro dispositivo actúa como un cliente que se conecta al punto de acceso del servidor y establece una conexión con el servidor a través de un puerto. (Todo se hace sin un enrutador en el medio).
El código del servidor se ve así: (cuando el servidor Android ejecuta el código, el dispositivo está en modo de conexión)
ServerSocket server = new ServerSocket(PORT);
while (true) {
Socket client;
client = server.accept();
ClientThread com = new ClientThread(client, this);
Thread t = new Thread(com);
t.start();
}
El código del cliente se ve así: (cuando el cliente de Android ejecuta este código, el dispositivo está conectado al punto de acceso)
Socket client = new Socket();
int serverIP = wifiManager.getDhcpInfo().serverAddress;
String stringIP = android.text.format.Formatter.formatIpAddress(serverIP);
InetAddress address = InetAddress.getByName(stringIP);
SocketAddress socketAddress = new InetSocketAddress(address, PORT);
client.connect(socketAddress);
Recibo el siguiente error en el cliente
java.net.ConnectException: failed to connect to /192.168.43.1 (port 12345): connect failed: ENETUNREACH (Network is unreachable)
at libcore.io.IoBridge.connect(IoBridge.java:114)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
at java.net.Socket.connect(Socket.java:842)
at java.net.Socket.connect(Socket.java:785)
at com.alternatewifimeshmessaging.HostManager.clientConnect(HostManager.java:283)
at com.alternatewifimeshmessaging.HostManager.client(HostManager.java:189)
at com.alternatewifimeshmessaging.HostManager.run(HostManager.java:59)
at java.lang.Thread.run(Thread.java:856)
Caused by: libcore.io.ErrnoException: connect failed: ENETUNREACH (Network is unreachable)
at libcore.io.Posix.connect(Native Method)
at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:85)
at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
at libcore.io.IoBridge.connect(IoBridge.java:112)
... 8 more
El servidor no da errores
Tengo el siguiente conjunto de permisos en el archivo de manifiesto de Android:
<uses-permission android:name="android.permission.INTERNET" >
</uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" >
</uses-permission>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" >
</uses-permission>
Idealmente, tendría que transferir algunos datos del servidor al cliente.
¿Qué estoy haciendo mal?
Al probarlo resulta que no se puede establecer la conexión en el dispositivo de anclaje.
Pero si invertimos el proceso y abrimos un serversocket en el cliente conectado. Y conéctese desde el dispositivo tethering, funcionará.
Entonces, invertir la comunicación es la respuesta.
En una conexión wifi conectada, el proveedor de conexión no puede funcionar como cliente. Entonces, debemos implementar una conexión de socket tcp bidireccional. Use un socket de servidor con un número de puerto en el dispositivo que está en modo de conexión a red. Este dispositivo actúa como un servidor. En el dispositivo del cliente use el socket para acceder al puerto del cliente con la dirección IP.
Lado del servidor
class ServerThread implements Runnable {
public void run() {
socket = new Socket();
try {
serverSocket = new ServerSocket(SERVERPORT);
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
try {
socket = serverSocket.accept();
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Lado del cliente
class ClientThread implements Runnable {
@Override
public void run() {
try {
socket = new Socket();
InetSocketAddress socketAddress = new InetSocketAddress(SERVER_IP, SERVERPORT);
socket.connect(socketAddress);
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}