I am creating one SerevrSocket with some port number.
But sometimes I get BindException saying Address already in use.
So is there any mechanism by which I can check before binding ServerSocket whether it is in use or not.
And also what is the best way of handling BindException?
sounds like you aren't closing your socket correctly before your program exits.
The socket needs to be closed in onDestroy method.
try {
ServerSocket server = new ServerSocket(0);
port = server.getLocalPort();
server.close();
}
catch (Exception e1){
Log.e("Error in Finding socket",e1.getMessage());
}
above code snippet gives you the free port available. But as mentioned earlier, check the socket closure for previous connections.
Related
I've written a small file transfer program for android using standard Java sockets. The program works fine except for the following case:
I connect two android devices A and B over WiFi tethering connection. Device A is sharing the connection (enabled as wireless hotspot). When I run java server on A and client on B, the program works okay but when I run the server on device B, it can't accept any socket binding request from A. It doesn't throw any exception. Seems like the request is not reaching the server! However, both the devices are connected (ping test is okay in both directions). Can't I run socket server on a device connected as hotspot client? I thought once the networking is setup correctly, the application would work in any direction.
Also, Wireshark traces reveal nothing. What am I missing here? Please help! Here are my code snippets:
Server side (waiting for client connection):
while (true) {
try {
socket = serversocket.accept();
Runnable connectionHandler = new ConnectionHandler(
socket, fileArray, filepathNameArray,
SenderActivity.this, userID, handler);
new Thread(connectionHandler).start();
userID = userID + 1;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I would appreciate any kind of help! Thanks in advance.
I'm newbie on Android and Java programming and I'm stuck.
I was able to create a TCP/IP communication client (Over LAN) which sends text messages on a windows based web server. The code is working quite well on my Samsung Galaxy S Advance mobile phone which is currently running on 2.3.6. However trying the apk file on two other devices running Android 4.0 and Android 4.1 the App is running but no message arrives on the PC (test are preformed on the same network).
The function I'm using for sending packets is the following:
public void sednit(String IP,String MSG) {
try {
// Socket s = new Socket ("192.168.128.102",39999);
Socket s = new Socket (ipaddress,39999);
//outgoing stream redirect to socket
OutputStream out = s.getOutputStream();
PrintWriter output = new PrintWriter (out);
output.println(MSG);
output.flush();
BufferedReader input = new BufferedReader (new InputStreamReader(s.getInputStream)));
//read line(s)
String st = input.readLine();
//Close connection
s.close();
} catch (Exception e) {
// Toast.makeText(getApplicationContext(), e.toString(),Toast.LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), "Unable to communicate with player", Toast.LENGTH_LONG).show();
}
What Am I doing wrong?
Is there any limitation applied on Android 4 and newer or I have messed up my manifest file?
Thank you.
You are most likely getting a NetworkOnMainThread exception. Since Android Honeycomb, you are required to perform network operations in separate threads to improve UI responsiveness. The easiest ways to do this are to use an AsyncTask to manage your network operation if it's short, or to extend java.io.Thread if the connection needs to be maintained.
As Tomislav says in comment use Asynctask to network communication.
Also catch (Exception e) { Is an extremely bad Idea.. Catch the exceptions you are counting on, so that others may be thrown and you can see them. We have no idea what so ever what is going wrong with you program when you are doing this...
So please either do e.printStackTrace(); or remove the try/catch so we can get your logcat and help you.
I am currently working on an Android app to be linked into an existing product for my employer. The system is a device running firmware that is controllable via serial, ethernet, or wi-fi using a .NET Windows program, direct serial communication, or a control webpage. The Android app is meant to auto-connect control webpage so that the device is controllable from a phone without anyone having to manually find IP addresses. In order to do that, I need to be able to find IP addresses and determine whether or not the address corresponds to one of these firmware devices.
Essentially what I want to do is run through all IP addresses that the Android sees and send each one to the method above. This thing should ping the address with a firmware command and see what is sent back to determine whether the address corresponds to a firmware device. I’ve been doing that at the moment by sending a command like "HOME" or "GETINFO" (correctly formatted for the firmware, of course) and comparing what, if anything is sent back with the expected response. Commands like home also have the benefit of causing a physical response, so we know without a microchip debugger if the command has at least been received.
As it stands I have the correct address hardcoded and sent in to this method. I know that the app can load the webpage controls successfully using the same address as a URL, so it must be correct and the connection must be good, but direct communication to the device is not working. No physical response is observed and no information is sent back—the Input stream just times out and returns -1. What’s stumping me so badly about this is that as far as I can tell, I’m sending information exactly the same way as the .NET Windows controls, and yet it isn’t working.
One further note: I’m aware that sending the IP Address string to the socket constructor as a hostname probably should not work, but since no UnknownHostException is thrown, I know that the socket can resolve it to an IP Address. Correct?
My code is as follows:
private class NetworkTask extends AsyncTask<String, Boolean, Boolean> {
protected Boolean doInBackground(String... addr){
try {
String message = "<FHGETHUBINFO>";
byte[] input = new byte[8];
//addr is an array of string parameters containing a single IP address string. E.g. addr[0]=”192.168.199.108”
Socket s = new Socket(addr[0],80);
//outgoing stream redirect to socket
OutputStream out = s.getOutputStream();
out.write(message.getBytes());
Log.v(TAG, "output sent. Waiting for input.");
InputStream in = s.getInputStream();
//Skip the exclamation mark and newline. Verified that nothing is received even without a skip.
in.skip(2);
int numBytes = in.read(input,0,8);
Log.v(TAG, "Input received: "+numBytes);
String st = input.toString();
//Close connection
s.close();
if(st != "HUB INFO"){
return true;
}
else{
return false;
}
}
catch (UnknownHostException e) {
Log.v(TAG,"UnknownHostException: "+e.getMessage());
e.printStackTrace();
}
catch (IOException e) {
Log.v(TAG,"IOException: "+e.getMessage());
e.printStackTrace();
}
return false;
Thanks for any help you can give, I really appreciate it!
Agreed that I should be calling isReachable on the socket just for verification purposes, so thanks for the tip! However, it turned out the problem was that the device is not communicating on port 80, so the fact that I have the wrong port is definitely the source of the problem. Thank you for the advice, regardless.
I´m writing an android app that connects to a device through bluetooth using RFCOMM. I use the BluetoothChat example as basis for establishing a connection and everything works perfectly most of the time.
However, sometimes I cannot reconnect due to a message that the socket is already open:
RFCOMM_CreateConnection - already opened state:2, RFC state:4, MCB
state:5
This tends to happen if I connect to the device, close the app (call onDestroy()), reopen it and try to connect again, which results in the above.
I use this method for connecting in the ConnectThread(ref.BluetoothChat example):
Method m = device.getClass().getMethod("createRfcommSocket",new Class[] {int.class });
tmp = (BluetoothSocket) m.invoke(device, Integer.valueOf(1));
mmSocket = tmp;
The only thing that resolves this problem is turning off/on the Bluetooth of the Android phone.
This leads me to believe that the socket is not being closed in onDestroy() but still I´m calling on closing all threads as shown in the before mentioned example.
Any ideas would be appreciated.
I stumbled upon this one too, and here is the answer I found:
This error may happen, if you open and close a bluetooth socket connection multiple times.
Solution
Starting from API Level 14 there is a Method in BluetoothSocket called isConected(), which returns true, if this socket is already connected and false otherwise, here the original excerpt from the API:
Get the connection status of this socket, ie, whether there is an
active connection with remote device.
For API levels < 14 you can work around this issue by putting your Bluetooth Handling Thread to sleep after closing the connection - 1000 ms should be enough, here is an example (btDevice is of the type BluetoothDevice and has been initialized prior to the code snippet below):
try {
//Open the socket to an SPP device (UUID taken from Android API for createRfcommSocketToServiceRecord)
BluetoothSocket btSocket = btDevice.createRfcommSocketToServiceRecord("00001101-0000-1000-8000-00805F9B34FB");
//Connect to the socket
btSocket.connect();
//Close the socket
btSocket.close();
//Sleep time of 1000ms after closing the socket
SystemClock.sleep(POST_RESET_DELAY);
} catch (Throwable e) {
// Log error message
}
P.s. Instead of SystemClock.sleep you can also use Thread.sleep - however the SystemCock's sleep can't be interrupted, whereas the Thread.sleep can be interrupted, so it depends on your use-case which option better suits your purpose.
Source: Louis A. Prado
Hi
I'm trying to implement a bluetooth library and in it I want to connect an rfcomm socket once and then reuse it on all calls.
I want to know if it's connected or not in order to know if I should call the connect method.
I can't find anything in the source code for Bluetooth sockets since it's all native calls and there's no isConnected method defined in the API...
Does anyone have any experience with this?
I answered a similar question here. Starting from API Level 14 there is a isConnected method in the BluetoothSocket class available. For lower API levels, you may open a socket, do your work and close it again. However there are some thing you might have to consider, more in the linked answer.
I think you would have a member variable maintain the state of your connection. on successful connection set it to true, start a thread that loops always reading bytes from the sockets inputstream and if you get an IOException on that thread, set your flag to false.
isConnected() never works for me.
Try something like this:
try {
mSocket.connect()
} catch (IOException e) {
// Create a new socket
// mSocket.connect();
}