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
Related
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!
I'm feeling frustrating. After few day, I raise the white flag and ask for help.
I've used this code sample:
https://github.com/sht5/Android-tcp-server-and-client
But every time I try to establish a connection the memory uses is increased by about 500KB, so if the client disconnects and then reconnects without closing the application after many attempts the memory becomes saturated.
I have already tried various methods including
cancel (true) in AsyncTask's doInbackground,
close and force the socket and in, out objects to null
call System.gc ()
but none of this worked.
I'm not sure, but try to invoke AsyncTask as
new InitTCPClientTask().execute(new Void[0]);
instead of
InitTCPClientTask task = new InitTCPClientTask();
task.execute(new Void[0]);
I am trying to access a remote service via Volley and I end up in the on error response function
with the error:
02-26 10:29:53.491: D/MyApp(1592): java.net.SocketTimeoutException: failed to connect to 10.10.201.10 (port 443) after 5000ms
I can access this IP from my browser and I can see the interface fine.
Why do I get this from eclipse/volley? How can I debug this?
Did you set socket timeout value as 5000ms? If so, the request is failing since it is taking more than 5000ms. Try increasing the time out value in your custom Request class
public static final int MY_SOCKET_TIMEOUT_MS = 30000;
#Override
public Request<?> setRetryPolicy(RetryPolicy retryPolicy) {
retryPolicy = new DefaultRetryPolicy(MY_SOCKET_TIMEOUT_MS,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES , DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
return super.setRetryPolicy(retryPolicy);
}
What is the response time when you access it from browser? Is it shorter that that it takes in Eclipse?
If you know the average response time, you can increase timeout duration in Eclipse. Whatever library you use, there must be some method like setTimeout(int millis). There are not further things you can do unless you dig into the service codes.
Does your server return any kind of data, SocketTimeoutException occurr when there are blocking issues in read() or accept(), ie. if server doesn't return any data in defined timeout interval this exception will rise. It also could be a network problem, delay of some kind.
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!
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();