When you set a timeout on a socket with socket.seSoTimeout(5000); does the socket close or just stop listening after it times out? Will I have to open the socket again to continue listening or will it open automatically?
receivingSocket.setSoTimeout(5000); // set timer
try{
receivingSocket.receive(packet);
}
catch(SocketTimeoutException e){
System.out.println("### Timed out after 5 seconds.");
}
//will I have to reopen the socket here?
You can test your question by wrapping your try/catch in a while (true). The short answer is no, you do not have to reopen the socket. The setSoTimeout() is just telling the socket to wait this long for data before you try to do anything else.
byte[] buffer = new byte[1000];
DatagramPacket p = new DatagramPacket(buffer, buffer.length);
DatagramSocket receiveSocket = new DatagramSocket(5505, InetAddress.getByName("127.0.0.1"));
receiveSocket.setSoTimeout(5000);
while (true) {
try {
receiveSocket.receive(p);
} catch (SocketTimeoutException ste) {
System.out.println("### Timed out after 5 seconds");
}
}
Results (You can see that the socket is still reusable after it timesout):
As the documentation states:
If the timeout expires, a java.net.SocketTimeoutException is raised, though the ServerSocket is still valid
So no, it will not close the socket. Next time you're wondering how something works, check out the documentation
Related
I am experiencing problems when using a UDP datagram packet, in the program I bind a UDP port and listen messages on it. This normally works fine, but if the port remains idle for a long time, the program automatically terminates the UDP socket. Unfortunately, the log file is huge and it is difficult to find the exception. Please help me find a way to keep the UDP port alive forever. Thanks in advance.
Here is my code:
socket = new DatagramSocket(port);
setBindSocket(true);
socket.setSoTimeout(60000);
while(isBindSocket()) {
try {
byte[] buffur = new byte[512];
DatagramPacket inputPacket = new DatagramPacket(buffur, buffur.length);
inputPacket.setLength(buffur.length);
socket.receive(inputPacket);
byte [] bString = inputPacket.getData();
String hString = new String(bString);
} catch (SocketTimeoutException ste) {
} catch (Exception e) {
e.printStackTrace();
}
}
The following statement changes the socket's behavior when receiving - if no datagram arrives in 60 seconds, a SocketTimeoutException is thrown.
socket.setSoTimeout(60000);
Maybe I have misunderstood your question.
You're going to have to find that exception. Unless you set a read timeout, the read method will block forever.
I have TCP server-client application. It works but sometime something happens. Client connects to server but server says he doesn't accepted him.
Server side code:
while(!stopped){
try {
AcceptClient();
} catch(SocketTimeoutException ex){
continue;
} catch (IOException ex) {
System.err.println("AppServer: Client cannot be accepted.\n"+ex.getMessage()+"\n");
break;
}
...
private void AcceptClient() throws IOException {
clientSocket = serverSocket.accept();
clientSocket.setSoTimeout(200);
out = new ObjectOutputStream(clientSocket.getOutputStream());
in = new ObjectInputStream(clientSocket.getInputStream());
System.out.println("Accepted connection from "+clientSocket.getInetAddress());
}
Client side code:
try {
socket = new Socket(IPAddress, serverPort);
socket.setSoTimeout(5000);
out = new ObjectOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.getInputStream());
} catch (IOException e1) {
sendSystemMessage("DISCONNECTED");
sendSystemMessage(e1.getMessage());
return;
}
sendSystemMessage("CONNECTED");
If client connects the message:
Accepted connection from ... appears. But sometimes it doesn't appear
even if client sends message "CONNECTED"
Server is still runing the loop trying to get client and it is catching socketTimeoutException. Client is connected, sends message and waits for response.
I suspect a missing 'flush' inside your client's 'sendSystemMessage()'.
Unfortunately the constructor of ObjectInputStream attempts to read a header from the underlying stream (which is not very intuitive IMHO). So if the client fails to flush the data - the server may remain stuck on the line "in = new ObjectInputStream(socket.getInputStream())"...
As a side note it's usually better for a server to launch a thread per incoming client, but that's just a side remark (plus it obviously depends on requirements).
I found the problem. The communication on my net is too slow so it timeouts in getting inputstream. The solution has two parts. Flushing outputstream before getting inputstream. And set socket timout after streams are initialized.
serverside:
clientSocket = serverSocket.accept();
out = new ObjectOutputStream(clientSocket.getOutputStream());
out.flush()
in = new ObjectInputStream(clientSocket.getInputStream());
clientSocket.setSoTimeout(200);
I'm trying to create a socket that connects to a server. A user can manually enter the socket's IP address and IP port.
When the address and port are valid nothing goes wrong, but when they don't, it causes my entire app to freeze.
This is the code:
public void connect() {
try {
String txHostIP = settings.getString("txHostIP", "");
int txHostport = Integer.parseInt(settings.getString("txHostPort", ""));
//Where it all goes wrong. The program just hangs here for eternity
socket = new Socket(txHostIP, txHostport);
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
} catch (IOException e) {
showMessage(context, "Something went wrong");
}
}
What I want is for a message to pop up when no connection can be made but the program doesn't throw an exception if an IP port or address is incorrect.
How can I fix this? Any help is greatly appreciated!
EDIT:
I've added some System.out prints to show how the program hangs. I've also added a socket connect timeout of 5 seconds. Still the program won't even reach that block of code.
public void connect() {
try {
String txHostIP = settings.getString("txHostIP", "");
int txHostport = Integer.parseInt(settings.getString("txHostPort", ""));
System.out.println("1");
socket = new Socket(txHostIP, txHostport);
System.out.println("2");
socket.connect(socket.getLocalSocketAddress(), 5000);
System.out.println("3");
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
System.out.println("4");
} catch (IOException e) {
showMessage(context, "Something went wrong");
}
}
It just prints the 1 and then hangs on forever.
If you want to let the socket abort after a certain amount of time you have to do this:
int timeout = 5000;
int port = 1234;
String address = "localhost";
InetSocketAddress inetAddress = new InetSocketAddress(address, port);
Socket socket = new Socket();
socket.connect(inetAddress, timeout);
Otherways the socket will hang before you set the soTimeout. The connect method will throw an SocketTimeoutException if the remote host is not reachable.
Set a connection timeout of say, 5 seconds - run a counter based on the system clock and when the time is up, if it hasn't connected - throw the exception and cancel the connection.
I try to overcome a user disconnection detection on the server side using read timeout.
This is part of my code:
try {
socket.setSoTimeout(3000);
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
usr = new User(in.readUTF());
usr.connectUser();
int i=0;
while(true){
try{
i = in.readInt();
}
catch(SocketTimeoutException e){
System.Out.Println("Timeout");
// user connected, no data received
}
catch(EOFException e){
System.Out.Println("Disconnected");
// user disconnected
}
}
}
catch(Exception e){
// other exceptions
}
the code works fine except the "user disconnected" issue.
i want to catch the timeout exception and just continue waiting for data
but only if the client still connected.
why i never get other exception than SocketTimeoutException?
shouldn't i get IOException while in.readInt() can't use the socket because client disconnected?
is there any other simple way to detect user disconnection?
i mean as unwanted disconnection, like user had suddenly wifi shutdown etc...
thanks,
Lioz.
If the client didn't write anything within the timeout period, you get a SocketTimeoutException. If he disconnected instead of writing anything, you get an EOFException. Catch them separately. If you didn't get an EOFException, he didn't disconnect.
In my server located in a android device , if the number number of clients exceeds a specific number then the server close the socket. But in my client(other android device) i get a force close. How can i handle it gracefully?
Here is the connect part on my client:
serverIpAddress = serverIp.getText().toString();
if (!serverIpAddress.equals(""))
{
try
{
InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
SocketAddress sockaddr = new InetSocketAddress(serverAddr, 5000);
nsocket = new Socket();
nsocket.connect(sockaddr);
}catch(Exception e){
Log.i("Connect", "Connection Error");
}
if (nsocket.isConnected()){
score.setText("Your score is " + sc);
serverIp.setVisibility(View.GONE);
connectPhones.setVisibility(View.GONE);
enterIP.setVisibility(View.GONE);
Log.i("Connect", "Socket created, streams assigned");
Log.i("Connect", "Waiting for inital data..." + nsocket.isConnected());
receiveMsg();
}
Keep checking the socket connection is still open or not using isClosed() within an infinite loop, when server closes its connection, the isClosed() gets true, and then display a message or toast giving your desired reason to the user.
Sounds like whatever you are using to read the socket is a blocking read, and throws an exception when the socket closes and it is stuck at that read. Make sure that read is in a try block, and use the catch/finally to gracefully exit whatever you are doing at that moment.