Reading from a socket in a while loop - java

I want to implement the following functionality
while (true)
{
if client sends something
process it
else wait till something is send }
I have tried the following but it didn't work , it process one thing and then stop working
can anyone help me?
I have searched for such a case here but I didn't find anything . I would appreciate it if anyone can give an example of how to read from the socket inside a while loop as in the above description .
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(client.getInputStream()));
DataOutputStream outToclient =new DataOutputStream(client.getOutputStream());
while (true){
if ((request=inFromClient.readLine())!=null){
System.out.println("ser "+request);
msg1= new msgs();
if(msg1.IsListReq(request))
{
System.out.println("Ser :List req");
for (int i = 0; i <listOfFiles.length ; i++)
{
if (listOfFiles[i].isFile())
{
files[i] = listOfFiles[i].getName();
}
}
//prepare the respones
msg1.MakeFileListResponse (files);
outToclient.writeBytes(msg1.getMsg()+'\n');
} // end of processing List Request
} // end of first if statement
} end of while loop

You should have a condition to break your while loop or it will loop forever and your program will crash. This could be the problem you have.

Right now, you have an infinite loop. This differs from "read as long as there is input available" in that it will continue to read after input is no longer available.
Try something like this:
do
{
request = inFromClient.readLine();
if (request != null)
{
// do stuff.
}
} while (request != null);
The example above will stop reading when input is no longer available from the input stream.
For information about java and sockets check out the Oracle Java Socket Tutorial.
The work you describe will reside on a server.

Related

Iterative data gathering from server

I'm building a web server and client which I will use on a Raspberry Pi. The server is written in Python and every time a client connects to it, it will return data to the client. This is working well and when I access the server through my browser, I see the correct data and when I refresh the page I get new data, so that is working.
The problem is that I'm now writing a client in Java to access the server and collect the data. The reason I use here Java is that I'm more experienced in it and I find building a GUI more convenient; I use python on the raspberry pi because it offers me a simpler way of interacting with the hardware.
The java client code I have is this:
while (true) {
Socket socket = new Socket("192.168.0.37", 9315);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
try {
System.out.println("Getting");
out.write("GIMME DATA!");
out.flush();
System.out.println("receiving");
String data;
while ((data = in.readLine()) != null) {
System.out.println("Line: " + data);
}
socket.close();
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
}
}
This all works well, but I want to take the initial 3 objects out of the while loop (and obviously not close the connection). When I do that, I only can access the server once (it will give me the correct data) and on the second run in.readling() will return null which is weird. It seems that the inputstream only has the data from the initial run and no more bytes are written to it. To be clear, when putting the initial 3 objects IN the while loop, everything works well.
How can I take the objects out of the loop? It seems wasteful, time consuming and possibly memory consuming to create them every time...
Once you have reached to end of the file or BufferedReader reached to end of data, then how can it print again data from beginning. For example :
int i = 0;
BufferedReader br = new BufferedReader(new FileReader(new File("C:\\data.txt")));
while (true) {
String data = "";
while ((data = br.readLine()) != null) {
System.out.println(" data :" + data);
}
Thread.sleep(1000);
i++;
if (i == 2) {
break;
}
}
br.close();
In the above program, br reached to end of file, then it cannot point to the beginning. You have to create BufferedReder object every time when you enter while loop.

Won't loop reading strings through ObjectInputStream at the client socket

I have to send Strings from server to client side by socket at the server side i have following code
serverSocket=new ServerSocket(2004);
socket=serverSocket.accept();
System.out.println("request arrived");
this.outStream=new ObjectOutputStream(socket.getOutputStream());
outStream.flush();
this.inStream=new ObjectInputStream(socket.getInputStream());
//PoolTuningStrategy is an terface that is implemented by number of strategies
for ( PoolTuningStrategy st : this.strategies ) {
String name=st.getName();
System.out.println("inside Loop "+name);
outStream.writeObject(name);
outStream.flush();
}
outStream.writeObject("END NAMES...");
outStream.flush();
Now at the server side all the names are printed on the console correctly. Now at the client side i have the follwing code.
socket = new Socket("localhost", 2004);
System.out.println("Client starting");
this.outStream=new ObjectOutputStream(socket.getOutputStream());
outStream.flush();
this.inStream=new ObjectInputStream(socket.getInputStream());
do{
name=(String)this.inStream.readObject();
System.out.println(name);
}while(name.equals("END NAMES..."));
But only first string is printed at the client side, not all!
Plz help me
You are missing a ! in front of your equals() test in the while condition.
There is no 'ambiguity' here.
On the server side, make sure you are calling outStream.close(). You were also missing the !
I would recommend changing your code like this:
while( ! "END NAMES...".equals( (name=this.inStream.readObject())) ){
OR like this
while("END NAMES...".compareTo( (name=this.inStream.readObject())) != 0 ){
System.out.println(name);
}
Why? 1) By using "END NAMES...".equals(...), you avoid NullPointerException and your code can handle it gracefully. 2) You avoid ClassCastException. 3) You avoid IOException if you are already at the end of the stream. 4) It's leaner code.
Also, it may not be necessary to call flush() if you are calling close() on the stream. It can add extra burden by adding function calls. Note that we are not using C/C++. Java will flush when the buffer is full and at the end (EDIT: when you close it) of the stream automatically.

Best programming way to read streaming data

I am reading a streaming data from an TCP streaming software. I'm currently using while loop to read continuously. But I am not sure that if this is the best technique to read streaming data.
Following is the code i'm currently using:
Socket client=new Socket("169.254.99.2",1234);
System.out.println("Client connected ");
//getting the o/p stream of that connection
PrintStream out=new PrintStream(client.getOutputStream());
out.print("Hello from client\n");
out.flush();
//reading the response using input stream
BufferedReader in= new BufferedReader(new InputStreamReader(client.getInputStream()));
int a = 1;
int b= 1;
//
while(a==b){
// I'm just printing it out.
System.out.println("Response" + in.read());
}
Suggestions plz???
That loop would be the same as while(true), which is continuous. Also, I suggest running this in a thread.
After you init your socket and streams, I suggest calling a method like this:
Thread messageThread;
public void chatWithServer() {
messageThread = new Thread(new Runnable() {
public void run() {
String serverInput;
while((serverInput = in.readLine()) != null) {
//do code here
}
}
};
messageThread.start();
}
We put it in a thread so the loop doesn't hold up the rest of the client's code. (does not progress after loop)
The while loop initilizes serverInput within the parameters, so each time it loops, it re-inits serverInput so it doesn't constantly loop with the very first sent piece of data.
You gotta put it in parenthesis, because of course, while loops only accept boolean parameters (true/false). So, in pseudocode, if the InputStream always returns something, continue with the new recieved data.
I'm currently using while loop to read continuously.
That is the best technique for reading streaming data. However your loop must test for end of stream, which is signalled by read() retuning -1 in Java. Your 'a==b' test is pointless. There are several possible loop tests:
while (true) // with a break when you detect EOS
Or
while ((c = in.read()) != -1)
where 'c' is an 'int'.
But I am not sure that if this is the best technique to read streaming data.
Why not?

Error reading from a socket in java

On the one side of the socket I know the data is going into the socket correctly.
I set up a connection:
Connection sr = new Connection();
Server server = new Server("NAME", Interger.parseInt(port));
server.setIp(ip);
sr.setServer(server);
//I know my server connection code is correct because I can send and receive data in
//other areas of my program just fine
InputStream is = null;
try
{
is = sr.getChannel().socket().getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
StringBuffer text = new StringBuffer();
int k =0;
while(k != -1)
{
k = br.read();
text.append((char) k);
}
}
catch(Exception e)
{
//no errors ever get thrown
}
And then I only get about half my data, 10989 bytes out of a total 21398 that I send. The amount of bytes it reads varies but the data always ends with ..., "values": [" which in the data I send over looks like , ..., "values": ["", ""].
Keep reading until you have all the data. This question has been showing up about once a week lately. There's no guarantee that the network is going to have all your data show up at once.
You need to keep reading until you have all your data. How do you know how much data was sent? You should probably build a little protocol between the client/server that defines how much data is going to be sent, the server reads that little header and continues to read until the full message has been received.
Don't know if this could help you :
int k =0;
while((k = br.read()) != -1){
text.append((char) k);
}
1) In your case it is making the check on the next iteration, which may lead to appending of non-representable character(char of -1) to the end of text.
2) Never leave catch block empty, may be there is some execption.
So because my sending side of the socket was in c++ I was accidentally passing in a null ASCII value into the socket. And it is undocumented on the java side of the socket that if the read encounters a null value it treats it as an end of file. So it was prematurely ending the stream because it hit the null.

Java: Getting multiple lines from socket

I have a Java application that consists of a client and a server. The client sends encrypted commands to the server, and the server executes them.
The problem that I am having right now is that, with my encryption algorithm, sometimes the encrypted command contains "\n" or "\r" characters, which mess up my server code. This is because I am using the readLine() method, which stops when it finds a line terminator. What I need is a way to read all the characters the client sends into one string.
Here is my code:
public void run(){
System.out.println("Accepted Client!");
try{
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(), "ISO8859_1"));
out = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream(), "ISO8859_1"));
String clientCommand = null;
while(RunThread){
// read incoming stream
do{
clientCommand = in.readLine();
}while(clientCommand == null);
//decrypt the data
System.out.println("Client: " + clientCommand);
if(clientCommand.equalsIgnoreCase("quit")){
RunThread = false;
}else{
//do something
out.flush();
}
}
}catch(Exception e){
e.printStackTrace();
}
}
Everything I've tried (various forms of nested loops using the read() function) hasn't worked. I would welcome any help or suggestions. Thanks, everyone!
I don't see encryption in the code you posted, but usually it's not a good idea to rely on separator characters.
When sending binary data, you should prepend the length of the data to the stream, and then you know exactly how many bytes to expect (and when the message will end.) It's more efficient to do things that way too instead of looking for a newline character.
// read incoming stream
do{
clientCommand = in.readLine();
}while(clientCommand == null);
That == null seems wrong
Try
String line = null;
do {
line = in.readLine ();
clientCommand += line
} while (line != null);
One thing you must do, when working with TCP/IP, is to send the message length before the actual message. The application level cannot foresee the package size the TCP level is delivering to the destiny. So, before your message, you have to send a header with the message size and the destiny would read just these bytes.
About readLine(), I think it's better use another approaches like streams. Shortly, one suggestion:
Socket oSocket = new Socket(sAddress, iPort);
PrintWriter out = new PrintWriter(oSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(oSocket.getInputStream()));
do{
clientCommand = in.readLine();
} while(clientCommand == null);
This makes no sense. readLine() only returns null at end of stream, so you are telling Java to loop infinitely at end of stream. I don't even understand why there is a loop at all. You don't want to ignore any input from the client, you want to process it all. You should read one line from the client, execute it, and read another line. Repeat until null, then close the socket.

Categories