Android socket always ending in timeout - java

I have made an android socket client application for android 2.3.3.
It sends a XML request, and then recieves an answer back from a cobol socket server.
The application works perfectly fine, my problem is that, once my client application has read all the data, it still hangs around, waiting for the timeout limit for some reason.
Heres the code:
Socket socket = new Socket(serverIpAddress, serverPort);
socket.setSoTimeout(2000);
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
String request = ("Some XML Request");
out.println(request);
out.flush();
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Log.d("Nicklas", "Reader Oprettet");
Vector<String> v = new Vector<String>();
int i = 0;
Boolean KeepGoing = true;
while (KeepGoing)
{
try
{
String lol = in.readLine();
if (lol == null) { KeepGoing = false; }
v.add(new String(lol));
i++;
}
catch (Exception e)
{
Log.d("NickEEEXX", e.toString());
KeepGoing = false;
}
}
It always ends in the catch, with the exception "java.net.SocketTimeoutException" - even if it has sent and recieved the right data. This slows down the program a lot.
I am running this code as a method, not a thread, becouse i need to change the GUI in this section.
Does anyone have any ideas why it waits for the timeout?

Maybe lol is not null when there's no more data. Try checking against a blank string.

Related

Java sockets losing data: BufferedReader

I'm having the following problem in java: I am developing and app using java.net.Socket. It looks like that: There is a server with a thread which accepts and adds new client, and another thread which reads data from sockets and does "something" with it. Next to it there are clients. Client has data reader thread as well as a separate thread. I send the data as simple as:
socket.getOutputStream().write((content+"\n").getBytes());
on the client side and read it on the server like:
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String received;
while(true) {
try {
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
received = reader.readLine();
if(received == null) {
break;
}
System.out.println("SERVER " + received);
increaseReceivedCounter(1);
} catch(SocketException e) {
break;
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
System.out.println("SERVER RECEIVED "+ getReceivedCounter() + " MESSAGES!");
}
Now I just set the client to send some amount of messages like this:
try {
int n = 1000;
System.out.println("sending "+ n +" messages to " + client);
for(int i=0 ; i<n ; ++i) {
socket.getOutputStream().write((content+"\n").getBytes());
}
System.out.println("done sending " + n + " messages");
} catch (IOException e) {
e.printStackTrace();
}
The problem is that not all of the messages are transferred to a server. I have been looking for some solution for this but didn't manage to achieve 100% reliability. Is it even possible? I also tried with read instead of readLine but the result is the same: sometimes even 90% data loss. I think while server is working on the received data it ignores incoming packets and they're just lost.
Edit
Sockets initializations:
serverSocket = new ServerSocket(Server.PORT);//PORT = 9876, whatever
for the data reader on server side:
socket = serverSocket.accept();
on the client:
socket = new Socket("127.0.0.1", Server.PORT)
This is not an 'efficiency issue'. It is a bug in your code.
The problem is that not all of the messages are transferred to a server.
No, the problem is that you are losing data at the server. This is because you keep recreating BufferedReaders. You should create it once for the life of the socket.
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Remove this line.
The way you have it, you will lose data every time the prior BufferedReader has, err, buffered.
You also need to close the socket.

XML Response time ejabberd

At the moment I'm trying to develop an Android Application for Instant Messaging. I want to use ejabberd for this on an Ubuntu Server. There is just one problem.
When I try to connect to my ejabberd first with this xml-line:
<stream:stream to='x.x.x.x' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>
it takes very long to receive the answer (about 20 seconds, sometimes longer).
I just have this problem, when I send some "good" data to the Server. Sending some "bad" data, i receive the Error message very fast.
It's performed by an Android IntentService
I will Post my Code here too:
the attributes:
private Socket socket;
private String host = "x.x.x.x";
private int port = 5222;
private OutputStream out = null;
private String in = null;
the doInBackground():
this.socket = new Socket(host,port);
if(!this.socket.isConnected()){
Log.e("Socket","Socket nicht geöffnet");
}else{
Log.e("Socket","Socket erfolgreich geöffnet");
//create output stream
try {
this.out = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
//write to output stream
StringBuffer stringbuffer = new StringBuffer();
stringbuffer.append("<stream:stream to='5.175.8.41' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>");
//convert into bits and give it to outputstream
try {
this.out.write(String.valueOf(stringbuffer).getBytes("UTF-8"),0,String.valueOf(stringbuffer).getBytes().length);
out.flush();
Log.e("Connecting-out","Erstes Tupel erfolgreich gesendet.");
} catch (IOException e) {
e.printStackTrace();
}
//receive the answer from server
try {
Log.e("lol","lol");
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8"),200);
StringBuilder builder = new StringBuilder();
String aux;
aux = in.readLine();
this.in = builder.toString();
Log.e("...",aux);
} catch (IOException e) {
e.printStackTrace();
}
Log.e("Connecting-in",in);
i think especially these lines
StringBuilder builder = new StringBuilder();
String aux;
aux = in.readLine();
this.in = builder.toString();
take very long. But the strange thing is , that the Error message is read very fast. So it has to be the Server?
Can someone please help me?
Thanks in advance :)
You used readLine() and it waits for new line character.
On error, server generally disconnects the connection.
It is why you get error answer immediately.
I suggest you not using readLine().

Java Socket server side cannot read incoming line of text in play framework application

So I'm having some serious problems with Java's server side socket, which accepts connection, but it can't read anything from BufferedReader, which I have put to read the text stream from socket connection. Code for my threads run(), which I'm creating and running at the first time when any page is loaded.
public void run() {
try{
ServerSocket s = new ServerSocket(4100);
System.out.println("New tcp socket created");
Socket socket = s.accept();
System.out.println("New tcp update connection established.");
InputStream din = socket.getInputStream();
PrintWriter outp = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(din));
System.out.println("Streams created");
String inputline = "nothing yet...";
outp.println("hello from server");
while(true){
System.out.println("Got input from client:" + inputline);
inputline = in.readLine();
if(inputline == null || inputline.equals("exit")){
break;
}
}
}
catch(Exception e){
e.printStackTrace();
}
System.out.println("Updater thread exits.");
}
This prints out everything properly, except for Got input from client: + what ever my client sends with PrintWriter which outputs to a socket.
Client side example:
Socket s = new Socket(serverip, serverDownloadsUpdatePort);
OutputStream dout = s.getOutputStream();
PrintWriter outp = new PrintWriter(dout);
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
System.out.println(in.readLine());//This prints out properly, what server sends to client
outp.println("test connection");
outp.println("Can you hear me?");
outp.println("exit");
s.close();
Your client may not be sending end-of-line characters along with its input, causing your server to wait indefinitely at "in.readLine()".
The Javadoc for BufferedReader's readLine method (http://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html#readLine()) says: "Reads a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed." Make sure that your client is sending input that conforms to this rule.
I was able to see client input using your server with the following client Runnable (but only if I include the "\n"):
public void run() {
try{
Socket writeSocket = new Socket("localhost", 4100);
PrintWriter out =
new PrintWriter(writeSocket.getOutputStream(), true);
out.write("Hello there!\n");
out.flush();
}
catch(Exception e){
e.printStackTrace();
}
}
EDIT: When using println as in the submitter's client example, you don't need to worry about adding "\n", but you do need to flush the socket. One way to make sure this happens is by setting autoFlush=true in the PrintWriter constructor.
I found out that I forgot to set PrintWriter as auto flushable at client side and thats why it didn't work becouse stream didn't got flushed at any time.

Will setting a timeout on a socket work if you are reading a full line using a buffered reader?

I'm writing a socket client that sends a line down a socket connection and then waits for up to 45 seconds for a line back from the server.
I'm using a buffered reader like so:
Socket socket = null;
PrintWriter out = null;
BufferedReader in = null;
try {
socket = new Socket(host, 800);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
} catch (UnknownHostException e) {
listener.failedToConnectToHost(e);
return;
} catch (IOException e) {
listener.failedToConnectToHost(e);
return;
}
BufferedReader stdIn = new BufferedReader(
new InputStreamReader(System.in));
out.println("message");
try {
String response = in.readLine();
listener.responseRecived(response);
return;
} catch (IOException e) {
listener.errorReadingResponse(e);
return;
}
If I add the following line (Or something like it)
socket.setSoTimeout(45000);
What will happen after 45 seconds assuming that nothing has come through from the other end?
I assume I'll be catching an interrupted exception but I'm sure?
Will this even work? The docs for setSOTImeOut() imply that it's socket.read() that will timeout, I assume that the buffered reader is calling this somewhere down the stack, but assumption is the mother of all screw ups, so I just wanted to check.
The BufferedReader.readLine() method will throw a SocketTimeoutException after 45 seconds.
Apparently it does work and you get a SocketTimeoutException.

server client communication java

I have this client, the server information is not important. The output of this code is very random.
class Client {
public static void main(String args[]) throws Exception
{
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
Socket clientSocket = new Socket("127.0.0.1", 10004);//this will become the addr of the server you want to input.
InetAddress host = clientSocket.getInetAddress();
// System.out.println(host);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
boolean exit = false;
while (!exit) {
while (inFromServer.ready()) {
System.out.println(inFromServer.readLine());
}
String sentence = inFromUser.readLine();
outToServer.writeBytes(sentence + "\n");
}
clientSocket.close();
}
}
If I run this in debug mode, it has always the correct result. E.g.
please insert password
the user types pass
pass correct
please type command
and you type command
etc
etc
When it's not in debug mode, all goes wrong. I don't even get the initial request from server. What is going on? I think the read line might be executed too fast?
in.ready() does not wait for any data to be available. It the server hasn't sent the data yet when you client reads that line, you're going to skip the readLine() completely.
Just remove that while and do a plain readLine().
If there are phases where you need to wait for multiple lines from the server, you'll need to implement more logic. Usually, the server will send an "end of message" marker to signify to the client that it is done. For example, when the server is done, it could send the message "END-OF-MESSAGE". In the client code, you would do:
boolean serverDone = false;
while (!serverDone) {
String message = in.readLine();
if (message == null) {
// handle this problem: the server has closed the connection
serverDone = true; // or return, or throw
} else if ("END-OF-MESSAGE".equals(message)) {
serverDone = true;
}
}

Categories