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
Related
I am using reader.readLine() and sc.nextLine() to simulate the server and client. However, after I typed some words in the scanner, the server responded nothing. I think the problem is thread blocking, but I can't correct it. Could any one help point out where the sticking point is.
Here is the code for server.
public class Server {
public static LocalDateTime currentTime() {
return LocalDateTime.now();
}
public static void main(String[] args) throws IOException, InterruptedException {
ServerSocket ss = new ServerSocket(9091);
System.out.println("TCP server ready.\n");
Socket sock = ss.accept();
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(sock.getInputStream(), StandardCharsets.UTF_8))) {
try (BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(sock.getOutputStream(), StandardCharsets.UTF_8))) {
String cmd;
System.out.println("read in");
while ((cmd = reader.readLine()) != null) {
System.out.println("Rcvd: " + cmd);
if ("time".equals(cmd)) {
writer.write(currentTime() + "\n");
writer.flush();
} else {
writer.write("Sorry?\n");
writer.flush();
}
}
}
}
sock.close();
ss.close();
}
}
The code for client
public class Client {
public static void main(String[] args) throws IOException, InterruptedException {
InetAddress addr = InetAddress.getLoopbackAddress();
try (Socket sock = new Socket(addr, 9091)){
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(sock.getInputStream(), StandardCharsets.UTF_8))){
try (BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(sock.getOutputStream(), StandardCharsets.UTF_8))){
Scanner sc = new Scanner(System.in);
String cmd;
while (sc.hasNext()) {
cmd = sc.nextLine();
System.out.println("Scanned: " + cmd);
writer.write(cmd);
writer.flush();
String resp = reader.readLine();
System.out.println("Response: " + resp);
}
}
}
}
Use this in Client:
writer.write(cmd + "\n");
since the server read lines.
I have a multi-thread Java client-server app and found myself struggling with multiple lines communication. Here's what I mean
If I write a Server like this:
private static void startHandler(final Socket socket)
{
Thread thread = new Thread()
{
#Override
public void run()
{
try {
Scanner inputFromUser = new Scanner(socket.getInputStream());
PrintStream outPutToUser = new PrintStream(socket.getOutputStream(), true);
outPutToUser.println("Welcome!");
System.out.println(inputFromUser.nextLine());
} catch (IOException e) {
e.printStackTrace();
}
}
};
thread.start();
}
And write Client like this:
public static void main(String[] args) throws Exception
{
Scanner inputFromUser = new Scanner(System.in);
Socket socket = new Socket("127.0.0.1", 5555);
Scanner inputFromServer = new Scanner(socket.getInputStream());
PrintStream outputToServer = new PrintStream(socket.getOutputStream());
String greetingFromServer = inputFromServer.nextLine();
System.out.println(greetingFromServer);
outputToServer.println(inputFromUser.nextLine());
}
It works so well:
Server sends "Welcome" to the client
User input some string
This string gets printed in the server console
But if I try to make it more complicated like this:
private static void startHandler(final Socket socket)
{
Thread thread = new Thread()
{
#Override
public void run()
{
try {
Scanner inputFromUser = new Scanner(socket.getInputStream());
PrintStream outPutToUser = new PrintStream(socket.getOutputStream(), true);
outPutToUser.println("Welcome!");
sendInitialCommandsToUser(outPutToUser);
System.out.println(inputFromUser.nextLine());
} catch (IOException e) {
e.printStackTrace();
}
}
};
thread.start();
}
private static void sendInitialCommandsToUser(PrintStream writer)
{
writer.println("1 - Log In");
writer.println("2 - Sign up");
writer.println("3 - Exit");
}
Client:
public static void main(String[] args) throws Exception
{
Scanner inputFromUser = new Scanner(System.in);
Socket socket = new Socket("127.0.0.1", 5555);
Scanner inputFromServer = new Scanner(socket.getInputStream());
PrintStream outputToServer = new PrintStream(socket.getOutputStream());
String greetingFromServer = inputFromServer.nextLine();
System.out.println(greetingFromServer);
getMultipleLinesFromServer(inputFromServer);
outputToServer.println(inputFromUser.nextLine());
}
private static void getMultipleLinesFromServer(Scanner scanner)
{
while(scanner.hasNextLine())
{
System.out.println(scanner.nextLine());
}
}
It get's stucked on getMultipleLinesFromServer(Scanner scanner) method
Client output is only
Welcome!
1 - Log In
2 - Sign up
3 - Exit
And I cannot provide string to be printed on the server.. What's the problem?
If you want to read by line, BufferedReader is a good choice
Try this, worked fine on my IDEA
package com.zhouplus;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
private static void startHandler(final Socket socket) {
Thread thread = new Thread(() -> {
try {
BufferedReader inputFromUser = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter outPutToUser = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
outPutToUser.println("Welcome!");
sendInitialCommandsToUser(outPutToUser);
System.out.println("start readline!");
System.out.println(inputFromUser.readLine());
} catch (IOException e) {
e.printStackTrace();
}
});
thread.start();
}
private static void sendInitialCommandsToUser(PrintWriter writer) {
writer.println("1 - Log In");
writer.println("2 - Sign up");
writer.println("3 - Exit");
writer.flush();
}
public static void main(String[] argv) throws IOException {
ServerSocket ss = new ServerSocket(5555);
Socket accept = ss.accept();
startHandler(accept);
}
}
and the client
package com.zhouplus;
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
public class Client {
public static void main(String[] args) throws Exception {
Scanner inputFromUser = new Scanner(System.in);
Socket socket = new Socket("localhost", 5555);
BufferedReader inputFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter outputToServer = new PrintWriter(socket.getOutputStream());
String greetingFromServer = inputFromServer.readLine();
System.out.println(greetingFromServer);
new Thread(() -> {
String str = inputFromUser.nextLine();
outputToServer.println(str);
outputToServer.flush();
}).start();
getMultipleLinesFromServer(inputFromServer);
}
private static void getMultipleLinesFromServer(BufferedReader br) throws IOException {
String str;
while ((str = br.readLine()) != null) {
System.out.println(str);
}
System.out.println("over");
}
}
If you look at the Javadocs of the Scanner hasNextLine method...
Returns true if there is another line in the input of this scanner.
This method may block while waiting for input. The scanner does not
advance past any input.
It appears that once it has printed "3 - Exit" it is blocking to wait for more data from the server.
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);
I have a multiplayer java game(four client and a server) which all classes were in a single file i have decided to rewrite the main class and keep the code in multiple shorter classes.Everything seems to be fine (no syntax error or run time error), from Server side it seems to be fine but not from the client side
I decided to use Print statement to get to the bug , it seems that the client is not able to work over below code:
public class ServerManager implements Runnable {
public static BufferedReader in;
public static PrintWriter out;
private Socket socket;
#Override
public void run() {
try
{
socket = Connection.connectToServer(GameStatus.serverIP, GameStatus.serverPort);
if(socket != null) {
return;
} else {
}
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
The working version of application for this particular area , is as below
BufferedReader in;
PrintWriter out;
public static void main(String[] args) {
....
....
....
private class startClient implements Runnable {
private Socket socket;
#Override
public void run() {
try
{
try {
socket = new Socket(serverIP, serverPort);
} catch (Exception ex) {
return;
}
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
Does my code have any issues?
well , I had put the try in the beginning of socket connection , and catch the exception at the end of the class , just gave it a try and kept the catch right after the the socket connection and it worked.
try
{
try{
socket = Connection.connectToServer(GameStatus.serverIP, GameStatus.serverPort);
//if(socket != null) {
//return;
//} else {
// }
} catch (Exception ex){
JOptionPane.showMessageDialog(null, "Can not connect to server!");
if(ex.toString().trim().equals("java.net.SocketException: Connection reset"))
{
JOptionPane.showMessageDialog(null, "Server is down!\nThe game will now exit...");
System.exit(0);
}
//else
}
//}
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
I am trying to write a small program, that opens a server, creates a client that connects to this server and receives a message from it.
This is the Code so far
public static void main(String[] args) {
final ServerSocket serverSocket;
try {
serverSocket = new ServerSocket(12345);
Thread t = new Thread(){
public void run(){
try {
Socket server = serverSocket.accept();
PrintWriter writer = new PrintWriter(server.getOutputStream(), true);
writer.write("Hello World");
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
};
t.start();
Socket client = new Socket("localhost", 12345);
BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
String message = reader.readLine();
System.out.println("Received " + message);
} catch (IOException e1) {
e1.printStackTrace();
}
}
If i run program it keeps waiting in readLine() - so obviously the client does not receive the message from the server.
Has anyone got an idea why this isn' working?
Your reading thread is waiting for a newline in the data stream. Just change the server to use:
writer.write("Hello World\r\n");
and you'll get the result you were expecting. Alternatively, you can just close the server socket, and then readLine will return when it reaches the end of the data stream.
You should put the readline in a loop as follows:
public static void main(String[] args) {
final ServerSocket serverSocket;
try {
serverSocket = new ServerSocket(12345);
Thread t = new Thread() {
public void run() {
try {
Socket server = serverSocket.accept();
PrintWriter writer = new PrintWriter(server.getOutputStream(), true);
writer.write("Hello World");
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
};
t.start();
Socket client = new Socket("localhost", 12345);
BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
// Check this --------------------------------------------------->
String message = null;
while ((message = in.readLine()) != null) {
System.out.println("Received " + message);
break; //This break will exit the loop when the first message is sent by the server
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
You can read this documentation for further explanation: http://download.oracle.com/javase/tutorial/networking/sockets/