Here is my problem, have a server and a client class which communicate via 2 threads (MsgWriter and MsgReader)
To read the input and write it in a stream i use a scanner.
It works but the Scanner need an input twice to continue.
For example:
I write a Message
Your Message: a text.
So i want to send the message right after i hit "enter"
but i have to press enter another time to send the text.
I'm sorry, i'm very bad in explaining. however here is the Code of the MsgWriter Thread
public class MsgWriter extends Thread {
private Socket s;
private Buffer buffer = new Buffer();
public MsgWriter(Socket s) {
this.s = s;
}
public void run() {
String message = "";
BufferedReader br = null;
boolean end = false;
while(!end){
try{
synchronized (buffer) {
while (!buffer.isEmpty()) {
buffer.wait();
}
//buffer.put(s);
OutputStream out = s.getOutputStream();
PrintStream writer = new PrintStream(out);
Scanner input = new Scanner(System.in);
input.useDelimiter("\n");
if (input.nextLine().equals("")){
System.out.println("Your message: ");
message = input.next();
br = new BufferedReader(new StringReader(message));
if (input.hasNext("x")) {
br = new BufferedReader(new StringReader("Good Bye"));
end = true;
}
message = br.readLine();
writer.println(message);
System.out.println("-------------------------------");
}
buffer.notifyAll();
}
}catch(Exception ex){
System.out.println(ex.getMessage());
}
}
}
}
And the Output
ServerIP: localhost/127.0.0.1
Port number: 56763
++ Connected to Server
Your message:
hi server
Received: hi client
Let me know if you need the Code of the MsgReader Thread as-well.
You have this line if (input.nextLine().equals("")) which looks for an empty string input and this is the reason your code waits for the second 'Enter' press. Any specific reason why you require this in the code?
Related
I am building a server in Java, and the input feed is giving me trouble - its current setup cannot read more than one line, and it cannot read anything without "\n" at the end. Here is the current input loop:
BufferedReader input = new BufferedReader(new InputStreamReader(serverConnection.getInputStream()));
if(input.ready()){
StringBuilder text = new StringBuilder();
String line;
while((line = input.readLine()) != null){
text.append(line);
System.out.println(line);
}
sentData = text.toString();
return true;
}
My current loop using a BufferedReader cannot read more than one line of incoming data, and if there is no newline character, a timeout exception is thrown (I programmed it to do that), and the data is not read at all. It is, of course, unacceptable to have a listener that can only see one line of data, and stalls when the sent data is not formatted properly.
So I am looking for a method that allows the program to read any number of lines, and for the program to stop reading when it has reached the end of the data stream (even without a new line).
Any help is appreciated.
You're throwing away every odd-numbered line. Remove the readLine() inside the loop.
You can read from the InputStream directly into the StringBuilder. readLine() of BufferedReader will wait for \r or \n character. This looks like stalling.
int ch;
StringBuilder text = new StringBuilder();
while((ch = serverConnection.getInputStream().read())!= -1) { // -1 will be read at EOS
text.append((char)ch);
}
sentData = text.toString();
return true;
Update
The following piece of code is to demonstrate the difference between usage of BufferedReader and InputStream to read bytes and what is available to the user during read operation. BufferedReader will always give you lines which are either terminated by line breaks or by EOS. Whereas InputStream will make the available bytes to the user.
In scenarios where it is NOT necessary to close the streams, and the bytes transferred has it's own way to mark start and end of packets/messages, you will be using InputStream to read bytes. If you try using BufferedReader for these applications, the last line of the message will be made available once the server receives the next packet/message, unless you send each line with a line-break.
public static void main(String[] args) throws Exception {
new Thread(new BufferedReaderServer()).start();
new Thread(new InputStreamServer()).start();
final String requestString = "Line#1\nLine#2";
System.out.println("\nSending to BufferedReaderServer");
Socket clientSocket1 = new Socket(InetAddress.getLocalHost()
.getHostAddress(), 8003);
OutputStream outputStream1 = clientSocket1.getOutputStream();
outputStream1.write(requestString.getBytes());
Thread.sleep(6000);
outputStream1.close();
clientSocket1.close();
Thread.sleep(1000);
System.out.println("\nSending to InputStreamServer");
Socket clientSocket2 = new Socket(InetAddress.getLocalHost()
.getHostAddress(), 8004);
OutputStream outputStream2 = clientSocket2.getOutputStream();
outputStream2.write(requestString.getBytes());
Thread.sleep(6000);
outputStream2.close();
clientSocket2.close();
}
static class BufferedReaderServer implements Runnable {
public void run() {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(8003);
Socket socket = serverSocket.accept();
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
String s = null;
System.out.println("BufferedReaderServer read START");
while ((s = bufferedReader.readLine()) != null) {
System.out.println(s);
}
System.out.println("BufferedReaderServer read END");
socket.getInputStream().close();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
serverSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
static class InputStreamServer implements Runnable {
public void run() {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(8004);
Socket socket = serverSocket.accept();
System.out.println("InputStreamServer read START");
int ch;
while ((ch = socket.getInputStream().read()) != -1) {
System.out.print((char) ch);
}
System.out.println("\nInputStreamServer read END");
socket.getInputStream().close();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
serverSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
The issue what is being faced here could be due to non-closing of client socket. Depends on the user's application
I am trying to allow communication between one program (the program launcher, if you will) and the programs it launches via processbuilder. I have the output working fine, but the input seems to stop when it reaches the readline() method in helloworld (the created process).
Below is helloworld.java:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
public class helloworld {
public static void main (String[] args) {
System.out.println ("println(\"Hello World!\")");
System.out.println ("getInput()");
Scanner in = new Scanner(System.in);
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
String input = "";
try {
// wait until we have data to complete a readLine()
while (!br.ready()) {
Thread.sleep(200);
}
System.out.println("println(\"Attempting to resolve input\")");
input = br.readLine();
^This is where program hangs^
if(input != null){
System.out.println("println(\"This should appear\")");
}
System.out.println("println(\"input recieved " + input + "\")");
} catch (InterruptedException | IOException e) {
System.out.println("ConsoleInputReadTask() cancelled");
}
System.out.println("println(\"You said: " + input + "\")");
//System.out.println("println(\"You said: " + in. + "!\")");
in.close();
System.exit(0);
}
}
This is where the output (println) from the other process is recieved:
public void run() {
try {
//cfile = files[indexval].getAbsolutePath();
String[] commands =
{
"java", //Calling a java program
"-cp" , //Denoting class path
cfile.substring(0,cfile.lastIndexOf(File.separator) ), //File path
program}; //Class name
ProcessBuilder probuilder = new ProcessBuilder( commands );
//start the process
Process process = probuilder.start();
//Read out dir output
//probuilder.inheritIO(); //Can inherit all IO calls
InputStream is = process.getInputStream();
OutputStream os = process.getOutputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
BufferedReader br = new BufferedReader(isr);
String line;
/*System.out.printf("Output of running %s is:\n",
Arrays.toString(commands));*/
while ((line = br.readLine()) != null) {
myController.runCommand(line, "Please enter something!", bw);
//System.out.println(line);
}
br.close();
os.close();
} catch (IOException e){
e.printStackTrace();
}
System.out.println("programclosed");
}
And here is the function that it calls:
public synchronized void runCommand(String line, Object... arguments) throws IOException {
String[] tokens;
if(line.contains("(")){
tokens = line.split("\\(",2);
switch(tokens[0]){
case "println": //Println - format println(String strng)
tokens[1] = tokens[1].substring(1, tokens[1].length() - 2);
System.out.println(tokens[1]);
break;
case "getInput": //Get input - format getInput(String command, String message, BufferedWriter br)
Scanner reader = new Scanner(System.in);
System.out.println(arguments.length);
System.out.println(((String)arguments[0]));
BufferedWriter in = ((BufferedWriter)arguments[1]);
in.write(reader.nextLine());
System.out.println("sending input");
in.flush();
reader.close();
break;
default:
System.out.println("Invalid command recieved!");
}
} else
System.out.println("Invalid command recieved!");
}
The output I recieve is:
Hello World!
2
Please enter something!
This is a test input
sending input
Attempting to resolve input
As you can see, I successfully exit the while(!br.ready()) loop, and I stop at br.readLine();
I am aware inheritIO() exist, but for this case I am using the BufferedOuput to send commands which are then parsed and sent to the switch statement, which in turn calls the corresponding function. This is because multiple processes could be launched from the process manager, think of the fun when multiple System.in calls arrive, with nothing to determine which process it is for! In addition, this allows for me to call any type of function, even those not related to println or input.
I believe the issue here is a result of the following:
BufferedReader.ready() returns true if there are any characters available to be read. It does not guarantee that there are any carriage returns among them. (docs)
BufferedReader.readLine() looks for a carriage return to complete a line. If one is not found, it blocks.
BufferedWriter.write() does not automatically write a terminating carriage return.
To test whether this is actually the problem, replace this line in runCommand():
in.write(reader.nextLine());
with:
in.write(reader.nextLine() + "\n");
I am currently sending a request as shown below and was wanting to print out the response and exit. Is there a robust way of getting the whole response and then exiting, i.e., rather than breaking the loop after x lines or x seconds (which would have problematic cases)? Currently, the program never exits as the Scanner blocks waiting for more input. How else can I print out the response if not with some kind of loop/reader combination that might block?
public class PingHost {
public static void main(String[] args) throws Exception {
Socket s = new Socket("www.google.com", 80);
DataOutputStream out = new DataOutputStream(s.getOutputStream());
out.writeBytes("GET / HTTP/1.1\n\n");
Scanner sc = new Scanner(s.getInputStream());
while (sc.hasNext())
System.out.println(sc.nextLine());
System.out.println("never gets to here");
s.close();
}
}
I am not 100 percent sure what you wanna do here.
But if you wanna just get the html of the answering page and move on afterwards, then give this code sample a try:
/**
* Example call:<br>
* sendHTTPRequestAndSysoutData("http://www.google.com");
* #param target
*/
public static void sendHTTPRequestAndSysoutData(String target){
try{
URL my_url = new URL(target);
BufferedReader br = new BufferedReader(new InputStreamReader(my_url.openStream()));
String strTemp = "";
while (null != (strTemp = br.readLine())){
System.out.println(strTemp);
}
}
catch(IOException e){
e.printStackTrace();
}
}
I have to send and receive with server some stream using java.
The protocol is telnet and if I use cmd in windows with this commands:"telnet 10.0.1.5 9100" and after "^AI202" I have a response.
The code java:
import java.io.*;
import java.net.*;
public static void main(String[] args) throws SocketException, IOException {
Socket s = new Socket();
PrintWriter s_out = null;
BufferedReader s_in = null;
String remoteip = "10.0.1.5";
int remoteport = 9100;
s.connect(new InetSocketAddress(remoteip , remoteport));
s_out = new PrintWriter( s.getOutputStream(), true);
s_in = new BufferedReader(new InputStreamReader(s.getInputStream()));
String message = "^AI202";
try{
System.out.println(s_in.readLine());
}
catch(Error e){
System.out.println(e);
}
s_out.close();
s_in.close();
s.close();
}
The problem is the same: s_in call method readLine() and program cycle infinite.
I think System.out.println(s_in.readLine()); will try to read it over and over again, failing each time and causing infinite loop.
Try
String line ="";
while ((line = s_in.readLine()) != null) {
// Do what you want to do with line.
}
Java Socket BufferReader.readline get null
The problem is that the telnet protocol does not terminate commands with line breaks.
Change your read block to
try {
char [] cbuf = new char[7];
System.out.println(s_in.read(cbuf, 0, cbuf.length));
} catch(Error e){
System.out.println(e);
}
And you will get some input.
I have a thread in which data is scanning from standard input stream as:
1. Scanner scan = new Scanner(System.in);
2. while(true)
3. {
4. String str = scan.nextLine();
5. System.out.println(str);
6. }
I want to stop this thread by another thread. I heard it is not good to use Thread.stop(). Using some boolean flag also will not solve it as the pointer (program execution step) will be always at line 4. String str = scan.nextLine();
Is there any way that I can stop the thread?
I think this article will help you, it comes with a code example that solves the problem.
You could either use that code directly, or write a new closable InputStream class, wrapping up the logic described in this article.
public class ConsoleInputReadTask implements Callable<String> {
public String call() throws IOException {
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
System.out.println("ConsoleInputReadTask run() called.");
String input;
do {
System.out.println("Please type something: ");
try {
// wait until we have data to complete a readLine()
while (!br.ready()) {
Thread.sleep(200);
}
input = br.readLine();
} catch (InterruptedException e) {
System.out.println("ConsoleInputReadTask() cancelled");
return null;
}
} while ("".equals(input));
System.out.println("Thank You for providing input!");
return input;
}
}