I am writing a Client/Server program. When I tried to read String from client using scanner.nextLine() it does not wait for to write the text on console and process the next statement. I am writing program in BInary I/O because it is more efficient then text I/O.
DataInputStream fromServer = null;
DataOutputStream toServer = null;
Scanner scanner = new Scanner(System.in);
try{
socket = new Socket("localhost",8000);
toServer = new DataOutputStream
(socket.getOutputStream());
fromServer = new DataInputStream
( socket.getInputStream());
}
catch(IOException e){
System.out.println(" Error in connection: " + e);
e.printStackTrace();
}
System.out.println("Connection is successfully Established...");
try{
//This does not processing
setText = scanner.nextLine();
toServer.writeUTF(setText);
toServer.flush();
// Get area from the server
double area = fromServer.readDouble();
// Display to the text area
System.out.println("Text from Client " + setText + "\n");
System.out.println("Response from server " + area + '\n');
}
catch(IOException e){
System.out.println(" Error in connection: " + e);
e.printStackTrace();
}
The output is:
Text from Client
Response from server 45.22
As you can see the program does not take input from the console
If I used next() instead of nextLine() then it runs fine, but I want to read the line of text up to enter key.
Related
I'm using java and received some json string from a server. I received json strings with readUTF but there is some data lost. I didn't received first two character of the every json packet.
Another problem is there is delay to received json strings. For example server sent one json string and client could not received it until approximately 50 json strings sent by server and client shows all the json strings suddenly.
What is the main problems?
public void run() {
System.out.println("hi from thread" + id);
try {
clientSocket = new Socket("192.168.1.22", id);
output = new PrintStream(clientSocket.getOutputStream());
input = new DataInputStream(clientSocket.getInputStream());
inputLine = new DataInputStream(new BufferedInputStream(System.in));
}
catch( IOException e){
System.out.println(e);
}
String responseLine;
try{
while(true){
output.println( id + " ");
System.out.println("sent:" + id + " ");
responseLine = input.readUTF();
System.out.println("received: " + responseLine);
}
}
catch (IOException e) {
System.out.println(e);
}
}
Because of server send data with UTF format, so I cannot receive them with Bufferedreader
I've had this problem before with applications like this, the main cause is DataInputStream which expects input to be in a certain format which I assume is not being conformed to by the server, try using BufferedReader instead as so:
BufferedReader input = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
Then whenever you wish to read data just use
some_string_here = input.readLine();
Note this requires each data value sent to end with a end line character "\n" or "\r".
So, I just learned how to make sockets and all that good stuff in Java, and so my first try got me a message from the client, and then the client crashing. What was supposed to happen was get a message from the client, if that message is equal to this, then send data back. However, the if function for if the message was correct wasn't firing, even though the message was correct.
Even when I remove the if function to check if the string was right or not, the program still freezes up. And by the way, my server is a console application, and my client is a SWT application.
Here's the server code with the removed if function:
try {
System.out.println("Waiting for a connection...");
// Start a server
ServerSocket server = new ServerSocket(3211);
// Listen for anyone at that port
Socket socket = server.accept();
System.out.println("The client has connected!");
// Get the data being sent in
DataInputStream inputStream = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
DataOutputStream ouputStream = new DataOutputStream(socket.getOutputStream());
// Turn that into UTF-8
String data = inputStream.readUTF();
System.out.println("Received " + data);
ouputStream.writeUTF("Great!");
System.out.println("Awesome!");
socket.close();
inputStream.close();
ouputStream.close;
server.close();
System.out.println("Socket closed\n-----------------------------");
}
catch(IOException e) {
System.out.println(e);
}
And the client (which is fired when a button gets pressed):
try {
allMessagesTextBox.setText(allMessagesTextBox.getText() + "\nConnecting to the server...");
Socket socket = new Socket("192.168.1.206", 3211);
allMessagesTextBox.setText(allMessagesTextBox.getText() + "\nConnected to the server!");
DataInputStream input = new DataInputStream(System.in);
DataOutputStream output = new DataOutputStream(socket.getOutputStream());
output.writeUTF("sweet");
String data = input.readUTF();
allMessagesTextBox.setText(allMessagesTextBox.getText() + "\nSERVER: " + data);
input.close();
output.close();
socket.close();
}
catch (IOException er) {
allMessagesTextBox.setText(allMessagesTextBox.getText() + "\n" + er);
}
As soon as I press the button to try and start the connection (with the server already running), the client instantly freezes. It doesn't even send any of the "connecting to server" kind of stuff.
Any idea what's going wrong, and how to fix this?
Your client is reading from System.in. It should be reading from the socket input stream.
NB You only need to close the outermost output stream of a socket. That flushes it if necessary and closes the input stream and the socket. You're presently not only closing more than necessary but also in the wrong order,
Your socket is unable to send data because you did not called .flush() method on your outputstream reference. Use this one and you don't have to write flush() and close() method explicitely on streams
Server Code
System.out.println("Waiting for a connection...");
// Start a server
try (ServerSocket server = new ServerSocket(3211)) {
// Listen for anyone at that port
try (Socket socket = server.accept()) {
System.out.println("The client has connected!");
// Get the data being sent in
try (DataInputStream inputStream = new DataInputStream(new BufferedInputStream(socket.getInputStream()))) {
try (DataOutputStream ouputStream = new DataOutputStream(socket.getOutputStream())) {
// Turn that into UTF-8
String data = inputStream.readUTF();
System.out.println("Received " + data);
ouputStream.writeUTF("Great!");
System.out.println("Awesome!");
}
}
}
System.out.println("Socket closed\n-----------------------------");
} catch (IOException e) {
System.out.println(e);
}
Client Code
try {
allMessagesTextBox.setText(allMessagesTextBox.getText() + "\nConnecting to the server...");
try (Socket socket = new Socket("127.0.0.1", 3211)) {
allMessagesTextBox.setText(allMessagesTextBox.getText() + "\nConnected to the server!");
try (DataInputStream input = new DataInputStream(socket.getInputStream())) {
try (DataOutputStream output = new DataOutputStream(socket.getOutputStream())) {
output.writeUTF("sweet");
}
String data = input.readUTF();
System.out.println(String.format("data received from server '%s':\n", data));
allMessagesTextBox.setText(allMessagesTextBox.getText() + "\nSERVER: " + data);
}
}
} catch (IOException er) {
allMessagesTextBox.setText(allMessagesTextBox.getText() + "\n" + er);
}
Output on Server
Waiting for a connection...
The client has connected!
Received sweet
Awesome!
Socket closed
-----------------------------
Output on Client
data received from server 'Great!':
Now moving to problem in your code.
See the client side code you have written DataInputStream input = new DataInputStream(System.in); instead of DataInputStream input = new DataInputStream(socket.getInputStream())
which causes the failure in receiving message from server
Right now, I'm trying to make a server that can display messages to the client when they connect (through localhost). When I connect through telnet, it gives me weird indentation. The code for the server is:
private ServerSocket middleman;
private int port = 8080;
private Socket client;
protected void createSocketServer()
{
try
{
while (true){
middleman = new ServerSocket(port);
client = middleman.accept();
middleman.close();
PrintWriter out = new PrintWriter(client.getOutputStream(),true);
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String line;
//Client stuff
DataOutputStream dOut = new DataOutputStream(client.getOutputStream());
while((line = in.readLine()) != null)
{
System.out.println("echo: " + line);
dOut.writeByte(1);
dOut.writeUTF("Good day to you user. Here is a selection of poems " + "\n");
dOut.writeUTF("1. Cupcake Poem" + "\n");
dOut.flush();
//Response
if(line.equals("cupcake")){
try{
FileReader fileReader = new FileReader(poem);
BufferedReader bufferedReader = new BufferedReader(fileReader);
StringBuffer stringBuffer = new StringBuffer();
String poemLine;
while((poemLine = bufferedReader.readLine()) != null){
stringBuffer.append(poemLine);
stringBuffer.append("\n");
}
fileReader.close();
System.out.println("Contents of file:");
//System.out.println(stringBuffer.toString());
dOut.writeUTF(stringBuffer.toString());
dOut.flush();
} catch(IOException e){
e.printStackTrace();
}
}
else{
System.out.println("wrong!, the line is:" + line);
}
}
}
}
catch(IOException e)
{
System.out.println(e);
}
}
On the client side, I'll open the command prompt and type telnet localhost 8080 then I'll type something like "fish". It will print
[?]Good day to you user. here is a selection of poems
1. Cupcake Poem
Why does it do this? If I type "cupcake" on client, it will read the file, but have weird spacing. Is this something to do with Telnet?
For telnet the correct end-of-line sequence is "\r\n". Newline by itself will only go down to the next line, but it will not back up to the first column, which what the carriage-return does.
Also note that the order matters, the telnet specifications says that it has to be "\r\n", in that order.
Also, you don't have to append the output with the newline-sequence like you do. You can write it all as a single string:
dOut.writeUTF("1. Cupcake Poem\r\n");
I am trying to create an application that will count the amount of times a button has been clicked. This client would connect to a server, and when the user clicks the button, it should increment the counter on the server. The server should then send back the current amount of clicks to the client. But that's where I'm having a bit of problems.
This is the relevant client-sided code.
public void actionPerformed(ActionEvent arg0) {
try {
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
String target = "";
bw.write("increment" + "\n");
bw.flush();
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String id = br.readLine();
System.out.println("test: " + id);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
The client stops at:
String id = br.readLine();
I just want to get the output from the server.
This is the relevant server-sided code.
public void run() {
try {
while (true) {
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is); //Create the input Streams
BufferedReader br = new BufferedReader(isr);
String input = br.readLine();
System.out.println("got input");
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
System.out.println("wrote to out");
if(input.equals("increment" + "\n")) {
totalBets++;
System.out.println("inif");
bw.write(totalBets);
System.out.println("wrote");
bw.flush();
System.out.println("flushed");
System.out.println("Total Bets: " + totalBets);
}
}
} catch (IOException e) {
log("Error handling client# " + clientNumber + ": " + e);
} finally {
try {
socket.close();
} catch (IOException e) {
log("Couldn't close a socket, what's going on?");
}
log("Connection with client# " + clientNumber + " closed");
}
}
I found that it also stops here:
String input = br.readLine();
I'm just trying to get the bw.write("imcrement") from the client, so the server can increment the counter, and send back the total clicks.
Any help?
Thank you.
You are writing the totalBets value using BufferedWriter.write(int).
This interprets the value as a single character. So, for example, if totalBets is 65, it writes the character 'A'!
Moreover, it does not add a newline. So the client reads that 'A' but tries to read more characters as it is trying to read a whole line. Remember that you have to write lines to read lines.
Thus, you should replace the part that writes totalBets with:
bw.write(String.valueOf(totalBets));
bw.newLine();
Also remember, as I pointed in a comment, that you have to write a line with a \n (or preferably BufferedWriter.newLine()), but when you read the line on the other side, the line separator is stripped away, so you should compare the string you expect without a \n.
You need to set TCP_NODELAY on the client's socket. The default is for data to be buffered until it will fill an entire packet. When the buffer is full, a packet is sent. However, for this protocol you want the data to be sent immediately so that the server can respond.
I frequently use wireshark when testing and debugging my networking code. It will show exactly what packets are sent and received. (note, however, that on Windows you can not capture from the loopback interface; this is a limitation of Windows and does not apply to other systems)
I'm testing out sockets on my local machine. I'm trying to run both a socket and server in one program using threads. My server is an echo server so that it sends back whatever message it receives. My problem is that when I start both threads, on both the client and server, they 'freeze' when they reach the part where I read from the input stream. It works fine up to the part where the client sends the message. Afterwards, it simply stops as it appears that the client is waiting for a message and so is the server even if I already sent a message to the server via writing to the outputstream. What's wrong with the code?
Client.java
#Override
public void run() {
try {
Socket socket = new Socket("localhost", 22600);
BufferedReader br = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream()));
BufferedReader input = new BufferedReader(new InputStreamReader(
System.in));
System.out.println("Client 1");
while (true) {
System.out.print("\nEnter text : ");
String inputText = input.readLine();
writer.write(inputText);
System.out.println("Client 2");
System.out.println("Client 3");
String s = br.readLine();
System.out.println("CLIENT RECEIVED : " + s);
}
} catch (Exception e) {
e.printStackTrace();
}
}
Server.java
#Override
public void run() {
try {
ServerSocket server = new ServerSocket(22600);
Socket socket = server.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream()));
System.out.println("Server 1");
while (true) {
System.out.println("Server 2");
String s = br.readLine();
System.out.println("Server 3");
if (s == null) {
System.out.println("NULL SERVER SIDE ERROR");
break;
}
writer.write("ECHO : " + s);
System.out.println("SYSOUT ECHO " + s);
}
server.close();
} catch (Exception e) {
e.printStackTrace();
}
}
You are writing a string that does not have an end-of-line at its end.
String inputText = input.readLine();
writer.write(inputText);
System.out.println("Client 2");
The inputText string does not include the end-of-line you typed. And you write it as-is to the server. However, the server tries to read a line:
String s = br.readLine();
System.out.println("Server 3");
So it will keep waiting until the client sends in a newline. But by now the client is waiting for an answer from the server, and now they are deadlocked.
So, you should add a writer.newLine() to the client, as well as the server's echo, which suffers from the same issue. It's also recommended, after each write, to use writer.flush(), on both server and client. Otherwise, it may wait until the buffer is full before actually writing, and the same deadlock will result.
The readLine method of BufferedReader requires a new line terminator to return a value (unless the end of Stream is reached), and then returns the line without this character. So the Client
Reads a line from the user into the variable inputText
Client writes inputText to the OutputStream
Server receives data, but waits until it receives a new line (which it does not).
If you wish to use new line as a delimiter for communication, append this to the end of the data sent
writer.write(inputText + "\n");