Why can't I connect through socket - android

I'm making an android app that connects with PC. I'm using solution that I've found HERE
When I try to connect with PC by giving exact IP adress everything works fine. Phone connects fast with PC or (when server on PC isn't running) I get info about unability to connect fast. Here is code:
public class ConnectPhoneTask extends AsyncTask<String,Void,Boolean> {
#Override
protected Boolean doInBackground(String... params) {
boolean result = true;
try {
InetAddress serverAddr = InetAddress.getByName(params[0]);
socket = new Socket(serverAddr, Constants.SERVER_PORT);//Open socket on server IP and port
} catch (IOException e) {
Log.e("remotedroid", "Error while connecting", e);
result = false;
}
return result;
}
#Override
protected void onPostExecute(Boolean result)
{
isConnected = result;
Toast.makeText(context,isConnected?"Connected to server!":"Error while connecting",Toast.LENGTH_LONG).show();
try {
if(isConnected) {
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket
.getOutputStream())), true); //create output stream to send data to server
}
}catch (IOException e){
Log.e("remotedroid", "Error while creating OutWriter", e);
Toast.makeText(context,"Error while connecting",Toast.LENGTH_LONG).show();
}
}
}
But when I try to loop through IP adresses to find device that I am able to connect to it takes very long time, until timeout. Here is code:
public class DevicesListTask extends AsyncTask<String,Void,List<Device>>
{
#Override
protected void onPreExecute() {
pb.setVisibility(ProgressBar.VISIBLE);
}
#Override
protected List<Device> doInBackground(String... params) {
List<Device> devices=new ArrayList<Device>();
String device_ip;
Socket socket;
for(int i=0;i<4;i++)
{
device_ip=params[0]+Integer.toString(i);
try {
InetAddress serverAddr = InetAddress.getByName(device_ip);
socket = new Socket(serverAddr, 8988);
devices.add(new Device(device_ip,socket.getInetAddress().getHostName()));
} catch (IOException e) {
Log.e("remotedroid", "Error while connecting", e);
}
}
return devices;
}
#Override
protected void onPostExecute(List<Device> devices) {
pb.setVisibility(ProgressBar.INVISIBLE);
if(devices!=null)
{
Intent intent = new Intent(context,DevicesList.class);
String[] devicesIPS = new String[devices.size()];
String[] devicesNames = new String[devices.size()];
for(int i=0;i<devices.size();i++)
{
devicesIPS[i]=devices.get(i).getIP();
devicesNames[i]=devices.get(i).getName();
}
intent.putExtra("DEVICES_IPS",devicesIPS);
intent.putExtra("DEVICES_NAMES",devicesNames);
startActivity(intent);
}
else
{
Toast.makeText(context,"nope",Toast.LENGTH_LONG).show();
}
}
}
I just change a little bit code from example I linked above. What is wrong with this code?
Exception I get is:
java.net.ConnectException: failed to connect to /192.168.1.2 (port 8988): connect failed: ETIMEDOUT (Connection timed out)
I get it while trying to connect to my PC, but I get this exception only while looping through adresses and not in first example. While using code from first example i get connected instantly. What's wrong wit that second bit of code that connection times out?

You will get connect timeouts when you try to connect to IP addresses that don't exist. The default timeout is around a minute. If you're getting connect timeouts you can shorten them as follows:
Socket socket = new Socket(); // create an unconnected socket
int timeout = 5000; // in milliseconds, tune as required
socket.connect(new InetSocketAddress(serverAddr, 8989), timeout);
5 seconds is more than enough in most circumstances, you can work it down to 2-3 seconds, not less.

Did you set the internet permissions in the Manifest file for the app? If not, then Android is sock-blocking you.

Related

Serversocket.accept() not accepting connection in server side when implemented in a background service

I am trying to establish a client server socket connection with wifi direct using the demo WiFi direct app. The demo app works fine where the connection is being established when the activity is open but
if I create a background service and try to listen for socket connections, the server running in the background service does not accept connections.
The code is as given below:
Server:
public class MyBackgroundService extends Service implements ChannelListener, ConnectionInfoListener {
private Runnable runnable = new Runnable() {
#Override
public void run() {
// put your socket-code here
String filename= null;
// Toast t = Toast.makeText(context,"Opening a server socket",Toast.LENGTH_LONG);
// t.show();
DataInputStream inputstream = null;
try {
ServerSocket serverSocket = new ServerSocket(8988);
Log.e(WiFiDirectActivity.TAG, "Server: Socket opened");
Socket client = serverSocket.accept();
Log.e(WiFiDirectActivity.TAG, "Server: connection done");
....
}
#Override
public void onConnectionInfoAvailable(final WifiP2pInfo info) {
this.info = info;
if (info.groupFormed && info.isGroupOwner) {
Log.e(WiFiDirectActivity.TAG,"FileServeronConneitoninfo Background");
new Thread(runnable).start();
}
}
Client:
public class FileTransferService extends IntentService {
private static final int SOCKET_TIMEOUT = 0;
#Override
protected void onHandleIntent(Intent intent) {
Context context = getApplicationContext();
if (intent.getAction().equals(ACTION_SEND_FILE)) {
String filename= intent.getExtras().getString(EXTRAS_FILE_PATH);
String host = intent.getExtras().getString(EXTRAS_GROUP_OWNER_ADDRESS);
Socket socket = new Socket();
int port = intent.getExtras().getInt(EXTRAS_GROUP_OWNER_PORT);
DataOutputStream stream = null;
try {
Log.e(WiFiDirectActivity.TAG, "Opening client socket - ");
socket.bind(null);
Log.e(WiFiDirectActivity.TAG, "Opening client socket - ");
socket.connect((new InetSocketAddress(host, port)), SOCKET_TIMEOUT);
Log.e(WiFiDirectActivity.TAG, "Client socket - " + socket.isConnected());
// ...
}
catch (IOException e) {
Log.e(WiFiDirectActivity.TAG, "IOException in File transfer");
Log.e(WiFiDirectActivity.TAG, e.getMessage());
}
finally {
if (socket != null) {
if (socket.isConnected()) {
try {
socket.close();
stream.close();
} catch (IOException e) {
// Give up
e.printStackTrace();
}
}
}
}
The client side is getting timeout exception and both the lines after the connect and accept are not executing. Is there any possible reason?
I have put timeout 0 to prevent timeout exception but still there are no connections established. This is happening only in the background service but if I do this in activity everything works fine.
Thanks in advance.
Log Cat Output of server side:
01-28 11:21:12.391 E/wifidirectdemo: COnnection_Change_BackgroundService
01-28 11:21:12.392 E/wifidirectdemo: ConnectionInfo Available Background
01-28 11:21:12.392 E/wifidirectdemo: FileServeronConneitoninfo Background
01-28 11:21:12.394 E/wifidirectdemo: Server: Socket opened
01-28 11:21:22.877 E/wifidirectdemo: P2P peers changed

Android Socket Connectio Refused

I am having trouble connecting two android phones via socket i am using android debug bridge to connect the phones to my PC from which i can launch the emulator on the phones.
I launch the server on one phone and try to connect with the other however i get the following error on my client side:
W/System.err: java.net.ConnectException: failed to connect to /192.168.49.1 (port 8080): connect failed: ECONNREFUSED
Server
private class SocketServerThread extends Thread {
static final int SocketServerPORT = 8080;
#Override
public void run() {
try {
serverSocket = new ServerSocket(SocketServerPORT);
Log.d("Quiz", "Server creation connection success");
Log.d("Quiz", "Server local port "+serverSocket.getLocalPort());
Log.d("Quiz", "Server local port "+serverSocket.getInetAddress());
HostingScreen.this.runOnUiThread(new Runnable() {
#Override
public void run() {
}
});
while (true) {
Socket socket = serverSocket.accept();
count++;
message += "#" + count + " from " + socket.getInetAddress()
+ ":" + socket.getPort() + "\n";
HostingScreen.this.runOnUiThread(new Runnable() {
#Override
public void run() {
msg.setText(message);
}
});
SocketServerReplyThread socketServerReplyThread = new SocketServerReplyThread(
socket, count);
socketServerReplyThread.run();
}
} catch (IOException e) {
e.printStackTrace();
}
}
Client
#Override
protected Object doInBackground(Object[] params) {
Socket socket = null;
try {
socket = new Socket(host,port);
Log.d("Quiz", "Client socket success");
connected = true;
while (connected) {
try {
Log.d("Quiz", "Sending command");
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket
.getOutputStream())), true);
// where you issue the commands
} catch (Exception e) {
}
}
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(socket != null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
The port is hard coded to port 8080 for both the server and the client for the time being, the host address is found when i make a connection between the phones by using the following code:
Connection
private void onConnectionChanged(Intent intent) {
final NetworkInfo netInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
final WifiP2pInfo p2pInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO);
isConnected = netInfo.isConnected();
if (isConnected) {
//Get host connection info
wifiMgr.requestConnectionInfo(channel, new ConnectionInfoListener() {
#Override
public void onConnectionInfoAvailable(final WifiP2pInfo info) {
wifiMgr.requestGroupInfo(channel, new GroupInfoListener() {
#Override
public void onGroupInfoAvailable(WifiP2pGroup group) {
if (group == null)
return;
WiFiP2P.this.group = group;
Log.d(TAG, "Wifi p2p connection group is " + group.getNetworkName());
Log.d(TAG, "Group size " + group.getClientList().size());
fireOnConnectionSucceed(group.getNetworkName(), group.getPassphrase());
//create client if not host
if(info.isGroupOwner) {
Client client = new Client(8080, p2pInfo.groupOwnerAddress.getHostAddress());
client.execute();
Log.d(TAG, "Client launch success");
Log.d(TAG, "Host address " + p2pInfo.groupOwnerAddress.getHostAddress());
}
}
});
if (isConnected && !info.isGroupOwner) {
} else {
startDiscovery();
}
}
});
} else {
group = null;
fireOnConnectionLost();
}
}
I check to see if the person connected is the host or not, if not i launch the client passing the port and host address to the client which is an Aysnc task where the socket to connect is created.
The error occurs in the client when
socket = new Socket(host,port);
is used causing the error stated.
Any ideas as to what the problem could be? They both connect to each other over WiFi but when i try to connect to the server socket it fails.
Thanks in advance.
Edit:
To clear somethings up, i use the adb to get the app from my computer onto my phone from which i can launch the app.
I am connecting both phones using wifimanager i need to find which of the phones created the wifi group and then that person is the host of the server to which i can connect the problem arises when i try to launch a socket to connect to the host using the host address from the connect info.
I managed to solve my problem, it turns out the device which was hosting the server wasn't being designated the group owner.
config.groupOwnerIntent=0;
Setting the owner intent of connecting devices to 0 fixed the problem.

Getting socket timeout when receiving frequent requests at once

I attempting to build a remote controller for my laptop using my phone.
I written a server application that running on my laptop, the remote app used as a client to the server application.
I want to implement a mouse pad, the problem is when I am moving my finger over the "touch pad" too fast, I am receiving read time out on server side after few iterations.
Server code
final ExecutorService clientProcessingPool = Executors.newFixedThreadPool(20);
Runnable serverTask = new Runnable()
{
#Override
public void run()
{
ServerSocket serverSocket = null;
try
{
serverSocket = new ServerSocket(DEFAULT_PORT);
serverSocket.setReuseAddress(true);
_working = true;
while (_working)
{
Socket clientSocket = serverSocket.accept();
clientSocket.setSoTimeout(10000);
clientProcessingPool.submit(new ClientTask(clientSocket));
}
}
catch (IOException e)
{
System.err.println("Unable to process client request");
e.printStackTrace();
}
finally
{
try
{
if (serverSocket != null)
{
serverSocket.close();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
};
Thread serverThread = new Thread(serverTask);
serverThread.start();
private class ClientTask implements Runnable
{
private final Socket clientSocket;
private ClientTask(Socket clientSocket)
{
this.clientSocket = clientSocket;
}
#Override
public void run()
{
System.out.println("Got a client !");
try
{
System.out.println("Connected!");
DataOutputStream dOut = new DataOutputStream(clientSocket.getOutputStream());
DataInputStream dIn = new DataInputStream(clientSocket.getInputStream());
String request = dIn.readUTF();
parseRequest(request);
System.out.println("request=" + request);
dOut.writeUTF("Got the command");
dOut.flush(); // Send off the data
dIn.close();
dOut.close();
clientSocket.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
I thought maybe I will send the requests only if the distance from the starting position to end position is bigger than STEPS(a constant) and only then send the request. But I think the mouse won`t move fluidly.
Thanks.
RXAndroid and RXJava are perfect for asynchronously handling these request and will allow you to add a debounce to the frequent requests. Check out Reactive.io

Try to connect socket until server starts in AsyncTask

I want in AsyncTask my app to try to connect to server until the connection is done. If the server is running when i start the app, it works, but if i start tha app and then i start the server it says: java.io.IOException: fcntl failed: EBADF (Bad file number)
public class FetchData extends AsyncTask {
BufferedReader in;
InetSocketAddress socketAddress;
#Override
protected Object doInBackground(Object[] params) {
socketAddress = new InetSocketAddress("192.168.1.158", 9999);
while(!_socket.isConnected()) {
try {
_socket.connect(socketAddress);
Log.d("socket_status", "Socket is connected!");
break;
} catch (IOException e) {
Log.d("socket_status", e.toString());
e.printStackTrace();
}
}
return null;
}
}
UPDATE: _socket is created in onCreate method #Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_widget);
if(_socket == null)
_socket = new Socket();
-----------------------
}
This solved my problem: Does socket become unusable after connect() fails?
I had to create a new socket in the catch or finally block.

ServerSocket Android

Hey community I have the following ServerSocket which should listen to port 53000 and log any received data. However, I cannot seem to get past the server.accept() blocking call.
public void run() {
SocketServer server = new ServerSocket(53000);
//---buffer store for the stream---
byte[] buffer = new byte[1024];
//---bytes returned from read()---
int bytes;
//---keep listening to the InputStream until an
// exception occurs---
while (true) {
try {
socket = server.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String str = in.readLine();
Log.i("received response from server", str);
in.close();
socket.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
} catch (Exception e){
server.close();
Log.e(TAG, e.getMessage());
}
}
}
I have also given the application the INTERNET permission in the Manifest file.
()
To add to the mystery, I have also verified client responses get sent to that port.
Is there something in particular I need to do to make this work?
Thanks.
Your code is very messy and won't even compile. I made some adjustments so that i could test your code, and it's working fine. Here is the test application I used:
package com.test.stackoverflow
import java.io.BufferedReader;
public class ServerSocketTestActivity extends Activity {
/** Called when the activity is first created. */
private static String TAG = "ServerSocketTest";
private ServerSocket server;
Runnable conn = new Runnable() {
public void run() {
try {
server = new ServerSocket(53000);
while (true) {
Socket socket = server.accept();
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
String str = in.readLine();
Log.i("received response from server", str);
in.close();
socket.close();
}
} catch (IOException e) {
Log.e(TAG, e.getMessage());
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new Thread(conn).start();
}
#Override
protected void onPause() {
super.onPause();
if (server != null) {
try {
server.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Using this code and netcat running via adb shell I was able to connect and communicate with the application.
When working with The Client Declare these methods
To access Streams
// gets the input stream // ObjectInputStream input;
// gets the output stream // ObjectOutputStream output;
// ServerSocket server;
// Socket connection;
maybe you have a another class to access the socket;
server = new ServerSocket(5001, 100);
// step 1 create socket connection
server = new ServerSocket(5001, 100);
while(the condition is true)
// step 2 wait for connection
// step 3 get streams
// step 4 : process the connection
// step 5 : close connection

Categories

Resources