geniuses.
I want to used socket in Java.
Here is a part of my server side code:
ServerSocket ss = new ServerSocket(this.portNum);
while (!ss.isClosed()) {
Socket socket = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
System.out.println("reading");
StringBuffer sb = new StringBuffer();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
System.out.println("read");
System.out.println("writing");
bw.write(this.wsp.parse(new String(sb.toString())).toJSONString());
bw.newLine();
bw.flush();
System.out.println("wrote");
bw.close();
br.close();
socket.close();
}
ss.close();
And my client side (test) code is:
Socket socket = new Socket("143.248.135.60", 44450);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("writing");
bw.write(str);
bw.newLine();
bw.flush();
System.out.println("wrote");
System.out.println("reading");
StringBuffer sb = new StringBuffer();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
System.out.println("read");
br.close();
bw.close();
socket.close();
Both sides halt after printing "reading."
What's wrong with my codes?
Thank you for your help in advance!
Your application blocks at the servers site at this point:
while ((line = br.readLine()) != null) {
sb.append(line);
}
Your servers will read lines until the source stream gets closed (br.readLine() will return null when the end of stream has been reached). But this doesn't happen. It seems that your're expecting just a single line here so try this instead of the loop at the server side:
System.out.println("reading");
String line = br.readLine();
System.out.println("read");
Now about the name loop on the client side: The server will close the streams and the socket immediately after it has written its own data. So br.readLine() will return null on the client side after the first line was read. So it will do what you're expecting. But it will also works if you're replacing the code as I've suggested it for the server side.
Hope it helps.
Edit based on the clarification of the question (need to read multiple lines):
The easiest way based on your work is to use a control character like "End of transmission" (0x04 on ASCII).
Client code:
System.out.println("writing");
bw.write("Hello");
bw.newLine();
bw.write("World");
bw.newLine();
bw.write(0x04); // EOT control character
bw.newLine(); // This is needed for BufferedReader/Writer - even if we've used a EOT
bw.flush();
System.out.println("wrote");
Continued in the next commend...
Server code:
while ((line = br.readLine()) != null && !(line.length() > 0 && line.charAt(0) == 0x04)) {
sb.append(line).append(System.lineSeparator());
}
If you're not using ASCII or UTF8 please review your used encoding to choose the correct control character.
Related
I'm looking to read the contents of a URL and write them to file, this is working as expected but it's only writing it a single time even though the program console shows multiple lines.
Code:
PrintWriter writer = new PrintWriter("the-file-name.txt", "UTF-8");
while(true) {
URL oracle = new URL("https://linkToData.com");
BufferedReader in = new BufferedReader(new InputStreamReader(oracle.openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
writer.println(inputLine);
System.out.println(inputLine);
}
writer.close();
The data in the URL refreshes constantly so there should be different data each time as the console print shows but it's only writing the first instance to file.
The key is writer.close()! If you want to write the file anew every time, you have to reopen the Writer each time.
If you want to append file each time you have to flush writer instead of closing and close at the end.
PrintWriter writer = new PrintWriter("the-file-name.txt", "UTF-8");
while(condition) {
URL oracle = new URL("https://linkToData.com");
BufferedReader in = new BufferedReader(new InputStreamReader(oracle.openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
writer.println(inputLine);
System.out.println(inputLine);
}
writer.flush();
}
writer.close();
I've been having a problem with using a while loop surrounding a BufferedReader in Java. I'm doing some experiments with Sockets.
My current code:
InetAddress address = InetAddress.getByName(this.IP);
SocketAddress socketaddress = new InetSocketAddress(address, this.port);
Socket socket = new Socket();
socket.connect(socketaddress);
if(socket.isConnected()){
Executor.logger.info("Connection to proxy established!");
}
else {
Executor.logger.warning("Connection to proxy failed!");
socket.close();
return;
}
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String temp2;
while((temp2 = in.readLine()) != null){
Executor.logger.info("Running query says " + temp2);
}
But no matter what I've tried the code will not progress to the next line. It does not spam my logger with anything, it just suddenly stops and gets stuck.
This is client-side only and I am not in control of the receiver server-side.
Am I doing something wrong?
Thanks for any help in advance.
Edits
The server is a command-line that accepts a command with variables and returns with a code that tells you the outcome of what you just did. However, when you first connect it returns something like message, blank line, message, blank line which is the loop currently getting stuck.
After testing I have found an alternative variable that can be used to detect whether the BufferedReader is full or not.
If you change the ((temp2 = in.readLine()) != null) from this code:
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String temp2;
while((temp2 = in.readLine()) != null){
Executor.logger.info("Running query says " + temp2);
}
And use the boolean (in.ready()) instead:
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out.write("login " + this.user + " " + this.password);
out.flush();
String temp2;
while(in.ready()){
temp2 = in.readLine();
Executor.logger.info("Running query says " + temp2);
}
It will stop the loop when the BufferedRead has no more data to read and can be re-initialised again whenever necessary by copying the loop again.
The server receives remote client commands .. commandos received are properly treated and then sent back to the client .. but the client can not read the output, nothing appears in out.println ("ServerMessage");
Customer must read the received data from the server ..
Could anyone help?
Thanks!
SERVER:
String MsG2X90aXk11 = "";
Thread.sleep(100);
while ((MsG2X90aXk11 = ShellZ.readLine()) != null) {
BufferedWriter writeCommand = new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream()));
String message = MsG2X90aXk11;
writeCommand.write(message+"\n");
writeCommand.flush();
CLIENT:
BufferedReader in = null;
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
String m6x7NXaxn102 = null;
while ((m6x7NXaxn102 = in.readLine()) != null) {
System.out.println(m6x7NXaxn102);
}
You are trying to print the line variable. While your variable that reads each line from the input stream is m6x7NXaxn102
Change:
System.out.println(line);
To:
System.out.println(m6x7NXaxn102);
Or:
Change:
while((m6x7NXaxn102 = in.readLine()) != null)
To:
while((line = in.readLine()) != null)
Hope this helps. :)
PrintWriter out = new PrintWriter(DoDSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(DoDSocket.getInputStream()));
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String fromServer;
String fromUser;
while ((fromServer = in.readLine()) != null)
{
System.out.println(fromServer);
if ((fromUser= stdIn.readLine()) != null)
{
//System.out.println(fromUser);
out.println(fromUser);
}
}
In this code for a client, I've created a Print Writer and a buffered reader which communicate with a Server, I also have a separate reader which reads the System.in from the command line.
My problem at the moment is that if the server send the client a multi line string, I will have to press enter to receive each line. How can I edit this code so that every line is printed from the buffered reader from the server, before it checks what the user has typed, rather than checking after every individual line?
Why not do one loop after the other?:
PrintWriter out = new PrintWriter(DoDSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(DoDSocket.getInputStream()));
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String fromServer;
String fromUser;
while ((fromServer = in.readLine()) != null)
{
System.out.println(fromServer);
}
while ((fromUser = stdIn.readLine()) != null)
{
System.out.println(fromUser);
}
Error says the socket is closed... I can send to the server fine, I can recieve from the server fine, but as soon as I try to send and recieve I always get 'Socket is closed' error.
Server:
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String decodedString;
while ((decodedString = in.readLine()) != null) {
System.out.println(decodedString);
}
in.close();
OutputStreamWriter osw = new OutputStreamWriter(connection.getOutputStream());
osw.write("return: "+decodedString);
osw.flush();
osw.close();
Client:
Socket c = new Socket("localhost",4040);
OutputStreamWriter osw = new OutputStreamWriter(c.getOutputStream());
osw.write("Test");
osw.flush();
osw.close();
BufferedReader in = new BufferedReader(new InputStreamReader(c.getInputStream()));
String decodedString;
while ((decodedString = in.readLine()) != null) {
System.out.println(decodedString);
}
in.close();
c.close();
This is because when you're closing one of the stream's (osw.close();) - the socked gets closed as well.
From Socket.getOutputStream's javadoc:
Closing the returned {#link java.io.OutputStream OutputStream} will close the associated socket.
Try flushing the streams but close them only when you're done.