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.
Related
I have wrote the code for ping async task but while executing it is taking only group owner ip address and not of host in the InetSocketAddress function
the code is as below
public static class PingTask extends AsyncTask<String,Void,String>
{
private Context context;
public PingTask()
{
}
public PingTask(Context context)
{
this.context=context;
}
//private String grp_address=WifiBroadcastReceiver.address;
#Override
protected void onPreExecute() {
//super.onPreExecute();
Log.d("Method","******In pre Execute");
}
#Override
protected String doInBackground(String... voids) {
String gp=voids[0];
Socket socket=new Socket();
int port=9990;
int Socket_Timeout=500000;
try {
Log.d("GROUP OWNER ADDRESS","#########"+gp);
Log.d("Receive Activity", "Opening client socket - ");
socket.bind(null);
socket.connect(new InetSocketAddress(InetAddress.getByName("192.168.49.1"),9990), Socket_Timeout);
Log.d("Receive Activity", "Client socket - " + socket.isConnected());
} catch (Exception e) {
Log.e("Receive Activity", e.getMessage());
e.printStackTrace();
} finally {
if (socket != null) {
if (socket.isConnected()) {
try {
socket.close();
} catch (IOException e) {
// Give up
e.printStackTrace();
}
}
}
}
return gp;
}
#Override
protected void onPostExecute(String s) {
if(s!=null)
{
Log.d("Post Method","*****In post Execute");
Log.d("Post Method","*****In post Execute"+s);
}
And it is giving below error
2019-11-24 16:24:57.606 26016-26016/com.example.photo_sharing D/GROUP OWNER ADDRESS: 192.168.49.1
2019-11-24 16:24:57.607 26016-26016/com.example.photo_sharing D/IP ADDRESS: 192.168.0.2
2019-11-24 16:24:57.608 26016-26016/com.example.photo_sharing D/Method: ******In pre Execute
2019-11-24 16:24:57.609 26016-26016/com.example.photo_sharing D/Receive Activity: Opening client socket
2019-11-24 16:24:57.610 26016-26053/com.example.photo_sharing D/GROUP OWNER ADDRESS: #########192.168.49.1
2019-11-24 16:24:57.610 26016-26053/com.example.photo_sharing D/Receive Activity: Opening client socket -
2019-11-24 16:24:57.614 26016-26053/com.example.photo_sharing E/Receive Activity: failed to connect to /192.168.49.1 (port 9990) from /192.168.49.1 (port 44461) after 500000ms: isConnected failed: ECONNREFUSED (Connection refused)
While trying to create a simple Android app that allows me to send a simple string to an IoT device, I used code which initialised a new socket everytime it would send a string. I thought it would be better to have a socket send multiple strings before it would get closed again, but this turned out to be very slow. I am not experienced enough to realise what is going on here.
public class sendString extends AsyncTask<String, String, Socket> {
int brightness;
private int oldbrightness;
void changeBrightness(int newbright){
oldbrightness = brightness;
brightness = newbright;
}
#Override
protected Socket doInBackground(String... strings) {
try {
Socket socket = new Socket(strings[0], 80);
socket.setTcpNoDelay(true);
DataOutputStream DOS = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
while (!isCancelled()) {
if (oldbrightness != brightness) {
DOS.writeUTF("\"sr1\":" + brightness + " ");
DOS.flush();
}
}
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void onCancelled(){
return;
}
protected void onProgressUpdate(String... progress){
}
#Override
protected void onPostExecute(Socket socket){
return;
}
}
This is my code which sends multiple strings over one socket. The function is called when a seekbar is clicked, brightness is changed everytime the seekbar moves and cancel(true) is called when the seekbar is released. Is my code wrong or is there a different reason as to why this method would be so slow?
The old code:
public class sendString extends AsyncTask<String, Void, Socket> {
#Override
protected Socket doInBackground(String... strings) {
try {
Socket socket = new Socket(strings[0], 80);
DataOutputStream DOS = new DataOutputStream(socket.getOutputStream());
DOS.writeUTF(strings[1]);
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
This would get called everytime the seekbar moved.
The difference is that the first version executes in a CPU-smoking loop sending messages infinitely, while the second version executes exactly once per seek bar move, which should always be quicker.
You are comparing apples and oranges.
You should open the socket outside this method, prior to installing the seekbar listener, and only send one message per invocation.
I'm new to Android, somewhat new to socket programming. I have two devices, running Android 5.1, connected with WiFi direct (not sure if that's relevant). I have a service where the server listens for a request on a socket, then returns a reply back to the client.
Likewise the client code sends a request and listens for the reply from the server. The server is sending the response, but the client never gets the message and the socket times out.
Server test code:
while (true) {
try {
Log.i(TAG, "test waiting for a request");
mServer = new ServerSocket(PORT);
Socket socket = mServer.accept(); //Block to receive message //
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Log.i(TAG, "Message received! " + in.readLine());
String msg = "This is my reply.";
OutputStream outputStream = socket.getOutputStream();
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
out.println(msg);
out.flush();
out.close();
} catch (SocketException e) {
Log.e(TAG, "Socket Accept Interrupted", e);
} catch (IOException e) {
Log.e(TAG, "Socket Failure", e);
} finally {
if (mServer != null && mServer.isBound()) {
try {
mServer.close();
} catch (IOException ioException) {
Log.e(TAG, "Failed to close socket trying to recover from SocketException", ioException);
}
}
}
}
Client test code:
Socket socket = null;
SocketAddress addr = new InetSocketAddress(host, PORT);
int socketTOms = 5000;
try {
socket = new Socket(host, PORT);
socket.setKeepAlive(false);
String syncReq = "Request to server.";
//Send Request//
OutputStream outputStream = socket.getOutputStream();
outputStream.write(syncReq.getBytes());
socket.setSoTimeout(socketTOms);
//Rcv reply//
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Log.i(TAG, "Message received! " + in.readLine());
} catch (SocketTimeoutException e) {
Log.e(TAG, "Timeout while reading from socket: timeout=" + socketTOms);
} catch (Exception e) {
Log.e(TAG, "Exception", e);
} finally {
if (socket != null && socket.isConnected()) {
try {
socket.close();
} catch (IOException e) {
Log.e(TAG, "Exception while closing socket", e);
}
}
}
I'm running the server and client on two different devices through Android Studio and can see in the logs that the server receives the request and sends the reply, but the client always throws SocketTimeoutException. I saw else where that socket.setKeepAlive(false) would fix the problem, but it doesn't seem to have any effect.
Seems simple enough, but I can't see what I'm missing here.
May be try this line of code before infinite loop mServer = new ServerSocket(PORT);
Did you try to create thread in sever side app. This makes the process to run in parallel so that while server is waiting for request the application does not gets hang. First of all try this code for localhost . To find Inetaddress just use InetAddress.getLocalHost(). Then run this. For communication with different devices there is service provided that is called (NSD) (Network Service Discovary).
But if you want to run this way I have written a code for you.
Server side code
TextView textView;
Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=(TextView)findViewById(R.id.textView);
button=(Button)findViewById(R.id.button);
button.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
connect();
}
}
);
}
public void connect()
{
MyServer myServer= new MyServer();
myServer.setEventListener(this);
myServer.startListening();
}
#Override
public void Display(String message) {
textView.setText("Client - "+ message);
}
}
Client side code
TextView textView;
Button button;
Thread mThread;
Socket clientSocket;
Button sendBtn;
public String userText1;
ObjectOutputStream output;
EditText editText;
Object userText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=(TextView)findViewById(R.id.textView);
button=(Button)findViewById(R.id.button);
sendBtn=(Button)findViewById(R.id.sendBtn);
editText=(EditText)findViewById(R.id.editText);
sendBtn.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
userText=editText.getText().toString();
start();
}
}
);
public void start()
{
mThread= new Thread(new Runnable() {
#Override
public void run() {
try {
clientSocket = new Socket("127.0.0.1", 2001);
Log.v("binaya", "client socket created");
output = new ObjectOutputStream(clientSocket.getOutputStream());
output.writeObject(userText);
Message serverObj = Message.obtain();
ObjectInputStream input = new ObjectInputStream(clientSocket.getInputStream());
String strMsg = input.readObject().toString();
serverObj.obj = strMsg;
mHandler.sendMessage(serverObj);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
});
mThread.start();
}
Handler mHandler= new Handler()
{
#Override
public void handleMessage(Message msg) {
msgDisplay(msg.obj.toString());
}
};
private void msgDisplay(String msg) {
textView.setText("Server - " + msg);
}
We have used handler because we cannot touch user interface from inside runnable in this case.
Thanks
Figured this out ....
On the client side I was using outputStream.write(...) to send the request to the server as in:
String syncReq = "Request to server.";
OutputStream outputStream = socket.getOutputStream();
outputStream.write(syncReq.getBytes());
But reading it on the server with BufferedReader.readLine():
Socket socket = mServer.accept(); //Block to receive message //
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Log.i(TAG, "Message received! " + in.readLine());
My problem was that outputStream.write(...) does not append a '\n' at the end of the String, but in.readLine() on the server expects it. Therefore the server was blocking while waiting for '\n'; which in turn caused the client socket to timeout.
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.
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