How do I open up a ServerSocket in my android application? - android

Ok so I am doing something that seems like it should be very easy. I am basically trying to open up a ServerSocket connection and then wait for the client to connect.
Here is my code.
ServerSocket serverSocket = new ServerSocket(6543);
Socket clientSocket = serverSocket.accept();
Whenever my code hits, serverSocket.accept();, I am throwing the following exception.
bind failed: EADDRINUSE (Address already in use)
So obviously my next step was to check and see if another port would work, it did not. Next I restarted the device and tried running the app and I got the same exception. I have given my app INTERNET permission and the device is rooted.
Here are my network interfaces that show up.
lo: ::1%1
lo: 127.0.0.1
eth0: //IPV6 address
eth0: 192.168.1.127
EDIT 1
Here is the serverSocket object info that I get when debugging.
ServerSocket[addr=192.168.1.121/192.168.1.121,port=0,localport=1234]
EDIT 2
I have the following available constructors in my ServerSocket
new ServerSocket(int port)
new ServerSocket(int port, int backlog)
new ServerSocket(int port, int backlog, InetAddress localAddress)
I tried using the 3rd constructor and same exception.
new ServerSocket(4567, 0, InetAddress.getLocalHost());

Alright so I finally figured out why my application was throwing an exception and if anyone has some feedback on this or would like to provide an answer as to why this was happening. I would greatly appreciate it.
So in my Thread that I created I need to postback to the main thread to update some TextView's based upon what was happening with the server connection. Well since I can't update the main thread from my self created thread I needed to add a Handler object to that Thread in order to update the UI. Removing that Handler completely allowed my application to successfully create the ServerSocket without throwing an exception.
Does the Handler somehow run the code before hand or what was happening here?
The code.
RemoteServerRunnable test = new RemoteServerRunnable();
Handler handler = new Handler();
handler.post(test);
test.start();

Related

Android MulticastSocket closing implicitly

I seem to be having a small problem with MulticastSocket on Android: writing an SSDP-related application. The socket works just fine when I set everything up the first time, but when I stop discovery, and try to restart things, I just get a SocketException: Socket Closed. I'm not closing the socket, I'm simply stopping the Kotlin Coroutine that is responsible for calling socket.receive() in a loop. Example:
fun listenForPackets(): Flow<DatagramPacket> {
return flow {
multicastSocket.use {
val incomingBuffer = ByteArray(MULTICAST_DATAGRAM_SIZE)
while (true) {
val incomingPacket = DatagramPacket(incomingBuffer, incomingBuffer.size)
it.receive(incomingPacket)
emit(incomingPacket)
incomingPacket.length = incomingBuffer.size
}
}
}
}
The problem
So the problem is that when I try to call that function again, I get a SocketException: Socket Closed. The socket initialization code is run once, meaning that toggling discovery on/off will use the same socket multiple times; the following code is run once throughout the whole application:
multicastSocket = MulticastSocket(MULTICAST_PORT)
multicastSocket.reuseAddress = true
multicastSocket.joinGroup(multicastGroup)
multicastLock.acquire()
What I have tried
My first thought was that I was not cancelling the Kotlin Coroutine correctly. As a result, I switched to using typical Java Threads, to no avail. Starting the thread the first time works, but, restarting discovery yields the same problem. I have also tried to not leave the group, and keep the multicastLock acquired - same problem.
What works
What works is having the initialization code (where I assign the socket, join the group, and acquire lock) run every time I need to start a scan. At the end of the scan, I reset all of the variables (leave group, release lock, close socket). So my question becomes - is this the correct approach? Or am I simply doing something else wrong?
Just to re-iterate, I'm discovering packets just fine, the issue is with restarting the discovery. Thank you in advance for any help!

EADDRINUSE When creating server socket on google glass

I am developing a google glass/android application. It is a video streaming application that has a server/client setup where the phone/glasses is the server and hooks the pc up with the session description for playing the video. It works great on the android and everything runs fine but as soon as I try to test it on the google glass it throws an error at this line
sSocket = new ServerSocket(sPort);
The exception message says "EADDRINUSE" which I'm assuming means the port is already opened but I never opened it. Even if I had opened it and my program didn't close it I changed the port a couple of times and it still says it's in use.
Thanks
Tyler,
Google Glass, like android, consistently will have many of it's ports occupied by applications running in the background. When creating a socket for your server to listen on, you have two choices:
1) Have a predetermined list of ports you can choose to have your server listen on.
If you choose to do this, then you can simply have a datastructure (list, queue, heap [if you have some priority of which ports you would like to use], etc) which contain all of your ports, then you can simply traverse them until you find an open port.
This can be achieved in the following manner:
private ServerSocket allocatePort(List<Integer> myArray) throws IOException {
for (int individualPort : myArray) {
try {
return new ServerSocket(individualPort);
} catch (IOException io) {
continue; // An exception will be thrown if this port is currently in use. It's OK, let's try another port.
}
}
// When no ports are available, let's throw an exception stating we were unable to find an open port.
throw new IOException("we were unable to find an open port");
}
Then simply invoke this method within your as follows:
int[] arrayOfPorts = {5000, 5001, 5002, 8000, 8001, 8002, 8003};
List<Integer> myArray = new ArrayList<>();
myArray = IntStream.of(arrayOfPorts).boxed().collect(Collectors.toList());
ServerSocket sSocket = allocatePort(myArray);
2) If you don't mind which port to listen in on, you can use the constructor to pick any available port.
This can be achieved as follows:
ServerSocket sSocket = new ServerSocket(0);
You can read up more on ServerSocket's Javadocs. Notice under the parameter's subsection:
port - the port number, or 0 to use a port number that is automatically allocated.
Please let me know if you have any questions!

ServerSocket error EADDRINUSE

I know that this question has already been posted, but every time the answer was that you have to bind the socket after that you have set the option setReuseAddress(true).
This is the problem, I have a thread that is always runnning, and in this thread I have the following instructions:
tcpReceiver = new ServerSocket();
tcpReceiver.setReuseAddress(true);
tcpReceiver.setSoTimeout(10000);
tcpReceiver.bind(new InetSocketAddress(10001));
Even if I set the option "reuseAddress" and then I do my bind sometimes I get the so famous
java.net.BindException: bind failed: EADDRINUSE (Address already in use)
Anybody know why?
Thx

SocketS in Android

Here is a sample of my code
TextView textStatus = (TextView) findViewById(R.id.editText1);
ServerSocket serverSocket = new ServerSocket(SERVERPORT);
.
.
Socket client = serverSocket.accept();
.
.
textStatus.append("TEXT");
client.close();
This makes the android application force close. If I remove textStatus.append, than it works. Again, if I remove Socket client = ... and client.close(), it displays the TEXT on the screen.
So, the socket client = serverSocket.accept(); is affecting textStatus variable in some way.
Can anyone tell me what is wrong ?
textStatus is probably null. Check to make sure that R.id.editText1 is the actual id that you're using in your XML file.
Also, any potentially long running task should not be done on the UI thread. You're going to have very bad app preformance. Please see the Painless Threading article and try moving your server communication off to a different thread. Or consider using an IntentService instead. I prefer the IntentService.

Android UDP Timeout not responsing

When I execute this code in android emulator
dataByte = new byte[1024];
ds = new DatagramSocket();
ds.setSoTimeout(3000);
dp = new DatagramPacket(dataByte, dataByte.length);
ds.connect(InetAddress.getByName(params[0]), Integer.valueOf(params[1]));
dp.setData("remdroid_test".getBytes());
ds.setSoTimeout(3000);
ds.receive(dp);
It results in not responding, what should i do?
Alternative suggestions on how to test a udp connection using Android are welcome.
If you are executing this code inside an Activity, then you are blocking the UI thread. If you block the UI for too long, then Android will force close your application.
One solution is to use an AsyncTask. The best option is probably to run it on a Thread from within a Service though.

Categories

Resources