So i'm trying to make a server/client solution using BufferedReader and BufferedWriter, but it won't work! Using only DataInputStream and DataOutputStream worked perfectly fine, but nothing printed out with the Buffered objects. Where is my error?
public class TServer {
static final int PORT = 8001;
static final int QUEUE = 50;
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(PORT, QUEUE)) {
Socket socket = serverSocket.accept();
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter output = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
System.out.println(input.readLine());
output.write("this is the server!");
output.flush();
} catch (IOException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
public class TClient {
static final String HOST = "localhost";
static final int PORT = 8001;
public static void main(String[] args) {
try (Socket socket = new Socket(HOST, PORT)) {
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter output = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
output.write("this is the client");
output.flush();
System.out.println(input.readLine());
} catch (IOException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
Using only DataInputStream and DataOutputStream worked perfectly fine, but nothing printed out with the Buffered objects.
The Client is sending the following:
output.write("this is the client");
The Server is trying to read a line with the BufferedReader:
System.out.println(input.readLine());
But no line will be received as the end of line terminator is not sent (hence, the method will block (same goes for the Server, which does not send the end of line terminator)). See the API for BufferedReader, which states:
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.
You are using readLine method of BufferedReader, so you should write newline-terminated string in corresponding BufferedWriter. Like:
output.write("this is the client");
output.newLine();
Related
I am having problem even with this very basic client-server application. The client is not sending data/ the server is not receiving. I cannot understand where is the problem. I am even starting to think that i did not understand anything about sockets.
This is the Server code:
public class Server
{
public static void main(String args[])
{
try{
ServerSocket serverSocket = new ServerSocket(3000);
Socket socket = serverSocket.accept();
System.out.println("Client connected: "+socket.getInetAddress.toString());
Scanner scanner = new Scanner(socket.getInputStream());
while(true)
{
System.out.println(scanner.nextLine());
}
}catch(IOException e)
{
System.out.println("error");
}
}
}
This is the client code:
public class Client
{
public static void main(String args[])
{
Socket socket;
PrintWriter printWriter;
try {
socket = new Socket("127.0.0.1", 3000);
printWriter = new PrintWriter(socket.getOutputStream(), true);
while(true)
{
printWriter.write("frejwnnnnnnnnnnnnnnnnnnnnnnnnosfmxdawehtcielwhctowhg,vort,hyvorjtv,h");
printWriter.flush();
}
}catch(IOException e)
{
System.out.print("error\n");
}
}
}
If I run both on the same machine, the server prints correctly "client connected .....", but then prints no more.
What is the problem?
The server reads the next line. The client doesn't send any line ending. So the server can't possibly know that the line is supposed to be ended, and blocks until it finds an EOL in the stream. Or until the client closes its socket.
In client code, you decorate your output stream with PrintWriter, so you can use println.
Replace
printWriter.write("frejwnnnnn...rjtv,h");
printWriter.flush();
by:
printWriter.println("frejwnnnnn...rjtv,h");
Flush is useless since have request autoflush (true in PrintWriter constructor).
In server code, you can use a BuffererdReader decorator instead of Scanner:
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String inputLine;
while ((inputLine = br.readLine()) != null) {
System.out.println(inputLine);
}
So this is the first Server-Client I am trying to 'setup' but it does not work as I want it to. Here is What I want:
The Client to do: (see comments in the code for the Client)
A 'user input' should be read by the Client
Send the 'user input' to the server
receive back something from the server
The server to do: (See the comments in the code for Server)
receive the 'user input' that read by the client
Do something with the 'user input'
Send what was done in (2), back to the client.
It is not working the only right thing it is doing is that it receives the input from the 'user', that is it:
public class Cli {
BufferedReader in;
PrintWriter out;
Socket s;
public Cli(int port){
try {
s = new Socket("127.0.0.1", port);
out = new PrintWriter(s.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader
(s.getInputStream()));
} catch (UnknownHostException e) {
System.out.print("fel");
} catch (IOException e) {
System.out.print("fel");
}
}
public void startaClient(){
BufferedReader stdIn = new BufferedReader (new InputStreamReader(System.in));
try {
while(true){
String userInput = stdIn.readLine();// get the user input (1)
System.out.print("from user: " + userInput);
out.write(userInput); // sends to server (2)
System.out.println(in.readLine()); // receive from server(3)
}
} catch (Exception e){
System.out.println("fel1");
}
}
public static void main(String[] args){
Cli c=new Cli(4002);
c.startaClient();
}
Here is the code for the Server:
public class Ser {
ServerSocket s;
public Ser()throws Exception{
s = new ServerSocket(4002);
}
public void startaServern()throws Exception {
while (true) {
Socket socket = s.accept(); //waits for new clients, acceptera inkommande förfrågan
Trad t = new Trad(socket);
t.start();
}
}
public static void main(String[] args)throws Exception{
Ser b = new Ser();
b.startaServern();
}
}
public class Trad extends Thread {
Socket socket;
BufferedReader in;
PrintWriter out;
public Trad(Socket s){
socket=s;
try{
in = new BufferedReader(new InputStreamReader(socket.getInputStream())); //
out=new PrintWriter(socket.getOutputStream(),true);
}catch(Exception e){System.out.println("fel");}
}
public void run(){
while(true){
try{
String theInput = in.readLine(); //read, receive message from client (1)
String res = theInput+"blabla"; // do something with the message from the client (2)
out.write(res); // send it back to the client (3)
} catch(Exception e) {
System.out.println("fel1");
}
}
}
}
When you do readLine() it will read a line i.e. until it reaches a new line.
Unless you send a new line it will wait forever. I suggest you send a newline so the reader knows the line has ended.
Since you are using a PrintWriter the simplest solution is to use
out.println(res);
instead of out.write(res);
My code just do a simple task send a text from client's console to server and receive a reply. But my code doesn't work though. I keep sending text to server and no reply sending back. I have done a several example that plus 2 number given from client. I do this the same way but i can't figure out what is the problem.
Server:
public class Server {
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(8);
Socket client = server.accept();
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(client.getInputStream()));
BufferedWriter outToClient = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
String in = inFromClient.readLine(),out;
while(in!=null){
out = in+" from server";
outToClient.write(out);
outToClient.newLine();
outToClient.flush();
}
inFromClient.close();
outToClient.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Client:
public class Client {
public static void main(String[] args) {
try {
Socket client = new Socket("localhost", 8);
System.out.println("Connected to server");
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(client.getInputStream()));
BufferedWriter outToServer = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
Scanner input = new Scanner(System.in);
String strClient,strServer;
while(true){
System.out.print("Client: ");
strClient = input.nextLine();
outToServer.write(strClient);
strServer = inFromServer.readLine();
System.out.print("Server: ");
System.out.println(strServer);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
There are several problems with your code:
Your server is expecting to read a line and you're only writing text without a newline symbol:
Reading a line in server with: inFromClient.readLine()
Writing text without newline in client: outToServer.write(strClient);
Change this to outToServer.write(strClient + "\n");
You don't flush the writer of the client. Add a outToServer.flush(); after the line outToServer.write(...);
You only read 1 line in the server and don't read inside the loop again.
EDIT: To make it easier i'll post the corrected code here: (I've tried it and it works like a charm)
Client:
public class Client {
public static void main(String[] args) {
try (Socket client = new Socket("localhost", 8);
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(client.getInputStream()));
BufferedWriter outToServer = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
Scanner input = new Scanner(System.in)) {
System.out.println("Connected to server");
String strClient,strServer;
while(true){
System.out.print("Client: ");
strClient = input.nextLine();
outToServer.write(strClient);
outToServer.newLine();
outToServer.flush();
strServer = inFromServer.readLine();
System.out.println("Server: " + strServer);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Server:
public class Server {
public static void main(String[] args) {
try (ServerSocket server = new ServerSocket(8);
Socket client = server.accept();
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(client.getInputStream()));
BufferedWriter outToClient = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()))) {
String in = inFromClient.readLine(), out;
while(in != null){
out = in + " from server";
outToClient.write(out);
outToClient.newLine();
outToClient.flush();
in = inFromClient.readLine();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Please remark that this solution uses Javas ARM (Automatic resource management) for autoclosing streams and sockets. So this will not work before java 1.7!
I get the following error:
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:189)
at java.net.SocketInputStream.read(SocketInputStream.java:121)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at test.SocketTest.main(SocketTest.java:26)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
I don't know why I get it. Any idea?
I'm using this code:
for Client:
public class SocketTest {
public static void main(String[] args) {
try {
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 5000);
ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Request request = new Request();
request.setInputId("user_1233423333");
request.setOperation(3);
outputStream.writeObject(request);
outputStream.flush();
String s;
while ((s = reader.readLine()) != null) {
System.out.println(s);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
and for the Server:
public class ServerSocketTest {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(5000);
Socket socket = serverSocket.accept();
ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
Request request = (Request) inputStream.readObject();
System.out.println(request.getInputId());
System.out.println(request.getOperation());
writer.write("ok");
writer.flush();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
I think that this codes should work, but I don't know Why I get this error. Any idea, guys?
EDIT:
OS = windows 8.1 64-bit
I've tested on my Ubuntu and everything was ok.
Your test program is exiting without closing the socket. This causes the connection to be reset (TCP RST) instead of issuing an orderly close (TCP FIN). On some platforms.
Another problem is that you are reading lines in the client, but you aren't sending a line. You need to send a line terminator.
Client side
Try any one
readLine() method looks for a complete line or a string that is ended by new line character \n.
Use Scanner that contains hasNextLine() and nextLine() methods.
Server Side
Try any one
Append new line character \n in the message for e.g. ok\n.
Use PrintWriter instead of BufferedWriter and use println() method that automatically appends a new line character in the message. Use auto-flush property of the PrintWriter to avoid calling flush() method manually.
Complete sample code:
ServerSocketTest.java
public class ServerSocketTest {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(5000);
Socket socket = serverSocket.accept();
ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
PrintWriter writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()),
true);
System.out.println(inputStream.readObject());
writer.println("ok");
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
SocketTest.java
public class SocketTest {
public static void main(String[] args) {
try {
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 5000);
ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
Scanner scanner = new Scanner(new InputStreamReader(socket.getInputStream()));
outputStream.writeObject("Hello");
String s;
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
I have a simple socket/serversocket example that I'm trying to get running, but both the client and the server hang when their BufferedReaders try to read. Here is the code for each:
SERVER
package picturePerfect;
--imports--
public class PictureServer implements Runnable{
static ServerSocket serverSocket;
public static void main(String[] args) throws IOException {
serverSocket = new ServerSocket(2342);
Thread firstSessionThread = new Thread(new PictureServer());
firstSessionThread.start();
}
#Override
public void run() {
Socket socket = null;
try {
socket = serverSocket.accept();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String clientRequest = bufferedReader.readLine();
System.out.println(clientRequest);
PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);
printWriter.println("Sent from server!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
CLIENT
package picturePerfect;
--imports--
public class PictureClient {
public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException {
Socket socket = new Socket("localhost", 2342);
PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);
printWriter.write("Sent from client!");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String response = bufferedReader.readLine();
System.out.println(response);
socket.close();
}
}
This is the barest I could simplify my code to. I have a sample program that I've been following, which seems nearly exactly the same. This is the sample server and client (that does work):
SAMPLE SERVER
--imports--
public class Server implements Runnable{
static ServerSocket ss;
public static void main(String[] args) throws IOException {
ss = new ServerSocket(3142);
Thread thread = new Thread(new Server());
thread.start();
}
#Override
public void run() {
while ( true ) {
Socket s = null;
try {
s = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String operands = br.readLine();
System.out.println(operands + " was received");
PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
pw.println(operands + " right back!");
} catch ( IOException e ) {
e.printStackTrace();
}
}
}
}
SAMPLE CLIENT
--imports--
public class Server implements Runnable{
static ServerSocket ss;
public static void main(String[] args) throws IOException {
ss = new ServerSocket(3142);
Thread thread = new Thread(new Server());
thread.start();
}
#Override
public void run() {
while ( true ) {
Socket s = null;
try {
s = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String operands = br.readLine();
System.out.println(operands + " was received");
PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
pw.println(operands + " right back!");
} catch ( IOException e ) {
e.printStackTrace();
}
}
}
}
I've tried putting the while loop into my server and moving my client and server to the default package, but neither helped. I also tried using read() instead of readLine(), and ending the printWriter's lines with \r\n, but was just as unsuccessful there.
Why does my code hang on readLine(), especially when the sample code doesn't?
What readline() does is wait until it sees a new line character until it returns, hence readLine().
In your client, you do not write a new line. You use:
printWriter.write("Sent from client!");
Instead, write a newline character into the stream using println,
printWriter.println("Sent from client!");
Server expects to read line, so you need to add line separators after your massage. To do this instead of
printWriter.write("Sent from client!");
in client use
printWriter.println("Sent from client!");
// ^^^^^^^
or
printWriter.write("Sent from client!"+System.lineSeparator());
printWriter.flush();
You will need to flush yourself because autoflush in PrintWriter works only for println, printf, or format, not for write method