everyone! I'm developing an Android app that allows to chat with nearby devices that have installed this app. In order to accomplish this, I'm using the Wi-Fi P2P API and Network Service Discovery to search for such nearby devices. I've written the code for searching the nearby devices in a thread started by a Service. When a device is detected, the Service sends it (through a broadcast intent) to an Activity which displays the devices detected so far. The detected devices are added to a recyclerView and, when the user presses one of them, a connection must be established to such device. The Wi-Fi Direct connection gets established successfully (that is, the WifiP2pManager.connect() method succeeds) and the WIFI_P2P_CONNECTION_CHANGED_ACTION is caught. In the broadcast receiver, when such broadcast intent is caught, the following code is executed:
NetworkInfo networkInfo = (NetworkInfo) intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
if (networkInfo.isConnected()) {
mManager.requestConnectionInfo(mChannel, connectionInfoListener); }
With the requestConnectionInfo() method I can obtain more information about the connection, such as the IP address of the device I'm trying to connect to. To obtain such information, I provide an implementation of WifiP2pManager.ConnectionInfoListener to that method, which is denoted by the connectionInfoListener variable. This is the code of my implementation of WifiP2pManager.ConnectionInfoListener:
private WifiP2pManager.ConnectionInfoListener connectionInfoListener = new WifiP2pManager.ConnectionInfoListener() {
@Override
public void onConnectionInfoAvailable(WifiP2pInfo info) {
InetAddress deviceIP = info.groupOwnerAddress;
int port = servicesConnectionInfo.get(device);
ConnectThread connectThread = new ConnectThread(deviceIP, port, device);
connectThread.start();
"device" is an instance variable of my implementation of BroadcastReceiver which is not important right now. What is important, instead, is the ConnectThread thread. That's the thread that handles the code necessary to connect the socket between the two devices. When I try to connect to a detected device, ConnectThread, in its run() method, creates a new instance of ChatConnection passing the IP address and the port number previously obtained to this constructor:
public ChatConnection(InetAddress srvAddress, int srvPort, String macAddress) throws IOException {
...
connSocket = new Socket(srvAddress, srvPort);
...
}
And here is where the problem occurs. When I test my app on my physical device, all I get is this exception:
W/System.err: java.net.ConnectException: failed to connect to /192.168.49.1 (port 6770): connect failed: ECONNREFUSED (Connection refused)
Of course, I installed my app on a second physical device too, which gets successfully detected and a Wi-Fi Direct connection gets successfully established. But, when comes to this line of code:
connSocket = new Socket(srvAddress, srvPort);
that exception is thrown... I apologize for the length of this question, but I wanted to be the clearest possible. I really thank you in advance for any help.
EDIT: I forgot to mention the code for initializing the ServerSocket.
The ServerSocket is initialized in a thread that is started as soon as the Wi-Fi is enabled.
That is, when the WifiP2pBroadcastReceiver (an inner class of the app's Service which extends BroadcastReceiver) catches a WIFI_P2P_STATE_CHANGED_ACTION intent, it checks if the Wi-Fi is enabled and, if enabled, it starts the the thread where the ServerSocket is located:
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION)) {
int statoWiFi = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
if (statoWiFi == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
mNsdService = new NsdProviderThread();
mNsdService.start();
}
The ServerSocket is initialized in the run() method of NsdProviderThread:
public void run() {
...
try {
server = new ServerSocket(0);
} catch (IOException ex) {
return;
}
...
while (!Thread.currentThread().isInterrupted()) {
Socket clientSocket = null;
try {
clientSocket = server.accept();
} catch (IOException ex) {
break;
}
try {
ChatConnection chatConn = new ChatConnection(clientSocket);
synchronized (connections) {
connections.add(chatConn);
}
} catch (IOException ex) {
continue;
}
}
"server" is an instance variable of NsdProviderThread declared as ServerSocket.