I am doing socket programming. I took reference from below link:
http://examples.javacodegeeks.com/android/core/socket-core/android-socket-example/
Below is detail about my issue. I have created Android lib for this ServerThread (my project requirement), and this is used in test app.
Now test app connect to this through lib and do the process. First time it works perfectly fine, but if I closed and reopen it crashed with exception:
"EADDRINUSE (Address already in use)"
Also tried serverSocket.setReuseAddress(true) this but no luck.
My code:
public void run() {
Socket socket = null;
try {
serverSocket = new ServerSocket(SERVER_PORT);
serverSocket.setReuseAddress(true);
} catch (IOException e) {
Log.e(TAG, "exception1= " + e.getMessage());
}
while (!Thread.currentThread().isInterrupted()) {
try {
socket = serverSocket.accept();
Log.d(TAG, "server Connected.......!!!!");
communicationThread = new CommunicationThread(
socket);
commThread = new Thread(communicationThread);
commThread.start();
} catch (IOException e) {
Log.e(TAG, "exception 2=" + e.getMessage());
}
}
}
If I call serverSocket.close() I am getting exception 2 as server socket close. Communication thread is same as given in previous link.
You have to call setReuseAddress(true) before the socket is bound to the port. You are calling it after, because you are passing the port to the constructor, which will bind the socket immediately.
Try this instead:
serverSocket = new ServerSocket(); // <-- create an unbound socket first
serverSocket.setReuseAddress(true);
serverSocket.bind(new InetSocketAddress(SERVER_PORT)); // <-- now bind it
TCP (and probably some other) sockets can't reuse the same port for a period after closing. This is to prevent confusion if there's data on the network from an existing connection. You can override this behavior, but the default is to wait for a period of time before allowing reuse of the port.
The call to fix this is setReuseAddress(true) on the server socket. But I'm not sure if it needs to be called on the first socket or the second, or both.
Edit:
Here's a blog post describing the TCP socket TIME_WAIT state and why it exists: http://www.serverframework.com/asynchronousevents/2011/01/time-wait-and-its-design-implications-for-protocols-and-scalable-servers.html
While other answers pointed out the importance of setReuseAddress(true), another problem that could arise is to construct the ServerSocket twice and call bind with the same parameters. For example if you call twice the code run() of the question, serverSocket will be assigned to a new instance of the ServerSocket class, but the old one is still living until garbage collected. Now constructing with the port value as parameter equals to bind the ServerSocket object, and you are going to end up with two ServerSocket bound to the same address, which is forbidden hence the exception. So build your serverSocket with your chosen port only once!
Try to create the instance of SocketServer outside of the run() method.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState)
try {
// create a new instance of an unbound socket first
serverSocket = new ServerSocket();
} catch (IOException e) {
e.printStackTrace();
}
}
Related
I am trying to write a simple android chat app. I have created a service class which handles all the networking communication. The DatagramSocket binding is in a separate thread. Once in while I am getting this error and the app crashes:
java.net.BindException: bind failed: EADDRINUSE (Address already in use)
at libcore.io.IoBridge.bind(IoBridge.java:89)
at java.net.PlainDatagramSocketImpl.bind(PlainDatagramSocketImpl.java:68)
at java.net.DatagramSocket.createSocket(DatagramSocket.java:133)
at java.net.DatagramSocket.<init>(DatagramSocket.java:78)
and this is the code which prodruces it. The error occur on the line with new DatagramSocket How can I avoid this error? Thank you.
private class ComThread extends Thread {
private static final int BCAST_PORT = 8779;
DatagramSocket mSocket;
InetAddress myBcastIP, myLocalIP;
public ComThread() {
try {
myBcastIP = getBroadcastAddress();
if (D)
Log.d(TAG, "my bcast ip : " + myBcastIP);
myLocalIP = getLocalAddress();
if (D)
Log.d(TAG, "my local ip : " + myLocalIP);
if (mSocket == null) {
mSocket = new DatagramSocket(BCAST_PORT);
mSocket.setReuseAddress(true);
mSocket.setBroadcast(true);
}
} catch (IOException e) {
Log.e(TAG, "Could not make socket", e);
}
}
Since Sean asked for the code, I have translated Nikola's answer to the following code, which is similar to what I am using in my app, in case it is useful:
if (mSocket == null) {
mSocket = new DatagramSocket(null);
mSocket.setReuseAddress(true);
mSocket.setBroadcast(true);
mSocket.bind(new InetSocketAddress(BCAST_PORT));
}
You need to set SO_REUSEADDR before binding. Don't specify port in the constructor - create unbound socket instead with DatagramSocket(null), then set options, then bind() explicitly.
Another reason that I faced,
In case you access a method that using your socket from an external thread, you have to make sure that the thread won't access the method more than once in the same time(or in another words won't create the socket more than one time), and despite the send and receive methods of the DatagramSocket are threadsafe, the construction of the DatagramSocket object is not, so you have to just synchronize the method that is capable of creating the DatagramSocket socket:
synchronized public void my_datagram_socket() throws Exception{
// create the socket
// operations through the socket
// whatever you want
}
I try to create a Simple TCP Server on Android phone and waiting for client.
I only want to implement the connection between TCPServer and Client , it doesn't need to transmit any data.
I have the another application for client , It use to connect to this TCPServer.
The code of TCPServerthread is like the following.
private class TCPServerThread implements Runnable
{
#Override
public void run() {
// TODO Auto-generated method stub
try {
ServerSocket serverSocket = new ServerSocket(PORT);
//while loop
while (true) {
Log.i(TAG, "TCPServerThread...while loop");
try {
Socket socket = serverSocket.accept();
Log.i(TAG, "TCPServerThread...socket.getInetAddress() = " + socket.getInetAddress());
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
Log.i(TAG, "First IOException");
}
}
//while loop end
} catch (Exception e) {
// TODO: handle exception
//e.printStackTrace();
Log.i(TAG, "Second IOException");
}
}
}
But it seems stop at Socket socket = serverSocket.accept(); and doesn't show the log of TCPServerThread...socket.getInetAddress() = when the client try to connect to this Server.
DO I missing something for TCPServer ?
Is it mean the client doesn't connect to the Server when the code stop at Socket socket = serverSocket.accept(); ??
----------------------------EDIT----------------------------------------
Update the process.
The Server(Android Phone) open the WiFi-Hot-Spot, it also open the TCP-Server like the above code.
After Client connect to WiFi-Hot-Spot , the Client and the Server are in the same network.
The Client will get a IP address of gateway, and the Client try to connect to this IP address of gateway by TCP.
So the connection port and Server address seems correct for Client.
Your code is correct, but it seems that no one is connecting to your TCPserver.
To avoid this blocking situation on
Socket socket = serverSocket.accept();
you have to set the timeout option for your socket when you declare it
serverSocket.setSoTimeout(mTime);
;)
I'm trying to establish a bluetooth communication between an android phone/tablet (4.0.3), and a bluetooth device, which is an earring reader (Destron Fearring DTR3E, in case you want to know, which I don't suppose you do).
I paired the phone with the reader (the reader has the pairing passcode on a tag) from the bluetooth settings, bluetooth is on of course, and now I'm trying to listen to reads from the device, by means of BluetoothServerSocket. The problem is that the accept call never returns, so obviously I am doing something wrong. The communication is done using RFCOMM.
Code:
private class AcceptThread extends Thread {
private final BluetoothServerSocket mmServerSocket;
public AcceptThread() {
// Use a temporary object that is later assigned to mmServerSocket,
// because mmServerSocket is final
BluetoothServerSocket tmp = null;
try {
// MY_UUID is the app's UUID string, also used by the client code
String uuid = "00001101-0000-1000-8000-00805F9B34FB";
tmp = bluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord("pdfParserServer", UUID.fromString(uuid));
} catch (Exception e) {
e.printStackTrace();
}
mmServerSocket = tmp;
}
public void run() {
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned
while (true) {
try {
socket = mmServerSocket.accept();
} catch (IOException e) {
break;
}
// If a connection was accepted
if (socket != null) {
// Do work to manage the connection (in a separate thread)
try {
mmServerSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
}
/** Will cancel the listening socket, and cause the thread to finish */
public void cancel() {
try {
mmServerSocket.close();
} catch (IOException e) { }
}
}
Is there something I am missing?
Thank you!
The only reason that could cause the code never to come back from accept is that, the device "Destron Fearring DTR3E" you are trying to connect to, has actually a bluetoothserver socket and not a bluetooth client, hence, the device might be waiting for you to actually connect to it, in stead of you creating a bluetoothserver socket and waiting for it to connect to your android device, you should read the specs on the device and make sure that actually is you the one that has to open a connection on "Destron Fearring DTR3E" socket...
Hope this helps...
Regards!
I was trying to use SocketServer to setup a server
int i =1, PORT = 6666;
ServerSocket server;
Socket client;
try {
server = new ServerSocket(6666);
for(;;){
client = server.accept();//fail in here
textView.setText("server accept..." + i);
//new MyHttpServer(client, i, PORT).start();
i++;
}
} catch (IOException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
textView.setText("Fail...");
}
However, the app always stops in server.accept(). I have already add internet permission for this app. I don't know why?
Update:
I have found the reason. It is because thread cannot start from an Active instance. I was putted server.accept() in onStart without a thread. Now I open a new Runnable for it, then fixed
There could be multiple reasons why your application can not start the server. My initial guess would be that you are trying to run the code on an emulator or a device and you already have some other application listening on that port.
You must check/provide the logcat trace in order to get to the cause of the error.
I think so your app will wait for client with port 6666.
server.accept();// return socket
Above code will return socket if client is available.For more details and clearity you can refer these links::
http://www.happygeek.in/socket-programming-in-android
http://www.edumobile.org/android/android-development/socket-programming/
How can I open a specific port in android?
I have a server socket but the connection is rejected because the port is closed.
try {
ServerSocket server = new ServerSocket(2021);
Socket client = server.accept();
} catch (Exception e) {
// TODO Auto-generated catch block
a = false;
e.printStackTrace();
}
If you still havn't got it to work, I would suggest that you create an inner class that extends Thread to replace that whole new Thread() {...}.start() statement (I have always had trouble getting those to work exactly right when I try to declare an instance field, I just stick with creating/overriding methods in that kind of statement). I would make the inner class, say ClientAnsweringThread, have a constructor that takes in the Socket (client) as a parameter and then calls ProcessClientRequest(_client); in the run() method as you already have.
It looks that you are just missing a loop around the accept() call so you can accept multiple connections. Something like this:
ServerSocket server = new ServerSocket( port );
while ( true )
{
Socket client = server.accept();
ProcessClientRequest( client );
}
To illustrate what I meant in my comment:
ServerSocket server = new ServerSocket( port );
while ( true )
{
Socket client = server.accept();
new Thread () {
final Socket _client = client;
// This stuff runs in a separate thread all by itself
public void run () {
ProcessClientRequest(_client);
}
}.start();
}