I am trying to set up a server with a client and a handler. The client should ask for a string from the user. This should then be written to an OutputStream, get read in by the handler which then saves the string to its own OutputStream before passing it back to the client. I know that this program is completely pointless, I am just trying to get my head around how servers, clients and handlers work.
Here is my code so far:
Server
public class Server {
public static void main (String args[]) throws IOException {
int port = 8080;
ServerSocket server = new ServerSocket(port);
while (true) {
System.out.println("Waiting for client...");
Socket client = server.accept();
System.out.println("Client from "+client.getInetAddress()+" connected.");
Handler handler = new Handler(client);
handler.run();
}
}
}
Handler
class Handler extends Thread {
private Socket client;
public Handler(Socket c) {
client = c;
}
public void run() {
try {
Thread.sleep(3000);
System.out.println("1");
PrintWriter out = new PrintWriter(new OutputStreamWriter(client.getOutputStream()));
BufferedReader in =
new BufferedReader(new InputStreamReader(client.getInputStream(),
"UTF-8"));
System.out.println("2");
String message = in.readLine();
System.out.println("4");
System.out.println("5");
out.println(message);
out.flush();
client.close();
System.out.println("Finish");
} catch (IOException e1) {
e1.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Client
public class Client {
public static void main (String args[]) throws IOException {
Socket server = new Socket("127.0.0.1", 8080);
System.out.println("Attempting connection...");
Scanner scan = new Scanner (System.in);
System.out.println("Please enter a string:");
String message = scan.next();
PrintWriter out = new PrintWriter(new OutputStreamWriter(server.getOutputStream()));
BufferedReader in =
new BufferedReader(new InputStreamReader(server.getInputStream(),
"UTF-8"));
out.println(message);
String messageReturn = in.read();
scan.close();
System.out.println("Server said: " + messageReturn);
in.close();
out.close();
}
}
The problem is that the handler seems to hang when it tries to read the message in. This problem seems similar to the one presented here: Socket problem - readline won't work properly
But this solution isn't working for me. I have tried using objectInputStreams instead of my current solution, but this didn't work either.
I doubt whether your client code will compile. The return type for this is int.
String messageReturn = in.read();
Anyway, this should work:
package network;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class Client {
public static void main (String args[]) throws IOException {
Socket server = new Socket("127.0.0.1", 9890);
System.out.println("Attempting connection...");
Scanner scan = new Scanner (System.in);
System.out.println("Please enter a string:");
String message = scan.next();
PrintWriter out = new PrintWriter(new OutputStreamWriter(server.getOutputStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(server.getInputStream(), "UTF-8"));
out.println(message);
// NOTE this
String messageReturn = in.readLine();
scan.close();
System.out.println("Server said: " + messageReturn);
in.close();
out.close();
}
}
Note Port has been changed.
Server Output
Waiting for client...
Client from /127.0.0.1 connected.
1
Client Output
Attempting connection...
Please enter a string:
Hello
The problem might be that you do not send an escape sequence with your response. ReadLine() waits till it gets an escape. Try sending a "\n" with your response. There is an article about problems using readLine() and println() with sockets. It also shows how to solve it.
ReadLine() / Println() and sockets
Related
I'm practising WebSocket in java and wrote two simple programs which one of them is a server that starts listening in port 9090 and receives a string as input from the client then makes a string uppercase and returns back to the client.
The program has no error but for some reason, it does not work. I can't find out what is the problem.
After debuting it seems like the server doesn't receive the inputs string even though both sides connect to each other successfully. When the user inputs his/her string the client sends it to the server but the server doesn't receive it, therefore, both programs go to the wanting stage and the application will not respond.
could you please help me with the issue?
Thanks in advance
server-side code :
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class Main {
public static void main(String[] args) throws IOException {
// Start listening at port 9090
ServerSocket s = new ServerSocket(9090);
System.out.println("Started: " + s);
Socket socket = s.accept();
System.out.println("conecction accepted by " + socket);
try {
// Buffer reader to get input and save it as "in"
BufferedReader in = new BufferedReader(
new InputStreamReader(
socket.getInputStream()
)
);
// write the output as "out"
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream()
)
));
// A Loop for waiting to receive the input from the client
while (true) {
System.out.println("Watting for inpute line ...");
String line = in.readLine();
// print the input string to console to make sure it recive the input
System.out.println("inputed Line: " + line);
// sent back upper case string to client
out.println(line.toUpperCase());
out.flush();
}
}finally {
System.out.println("closing...");
socket.close();
}
}
}
The cline side code:
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws IOException {
// get the Address for localhost
InetAddress addr = InetAddress.getByName(null);
//Connect to the server on pprt 9090
Socket s = new Socket(addr,9090);
// read and write to server using buffer reader and printwriter
try{
BufferedReader in = new BufferedReader(
new InputStreamReader(
s.getInputStream()
)
);
PrintWriter out = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(s.getOutputStream())
)
);
//Get the Ipute string from user
Scanner input = new Scanner(System.in);
while (true){
System.out.println("Enter your text:");
String line = input.nextLine();
if(line.equals("quit"))
break;
// Sent the input string to the server using 'out'
out.println(line);
// Recive the upper case string from server
String response = in.readLine();
System.out.println("Echo:... " + response);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
System.out.println("closing...");
s.close();
}
}
}
The server side is waiting to read a line from the client, it should work if you flush the PrintWriter on the client side:
// Sent the input string to the server using 'out'
out.println(line);
out.flush();
I basically try to make a simple domain resolver using sockets.
I am pretty far and I its working how it is now. Except my main function where I try to make a thread which keeps listening and waiting for another call. After I type www.google.com it gives me the address but when I try it again, it does nothing. I think the socket closes or something. I wanted to use threads and while loops but I'm struggling with this problem for hours.
Client side ( EchoClient.java )
package tetst222;
import java.io.*;
import java.net.*;
public class EchoClient
{
public static void main(String[] args) throws IOException
{
try
{
Socket sock = new Socket("localhost", 1350);
PrintWriter printout = new PrintWriter(sock.getOutputStream(),true);
InputStream in = sock.getInputStream();
BufferedReader bin = new BufferedReader(new InputStreamReader(in));
String line;
while((line = bin.readLine()) != null)
{
System.out.println(line);
}
//sock.close();
}
catch(IOException ioe)
{
System.err.println(ioe);
}
}
}
And this code:
Server side ( EchoServer.java )
package tetst222;
import java.net.*;
import java.io.*;
import java.lang.*;
import java.util.*;
public class EchoServer //implements Runnable
{
public static void main(String[] args) throws IOException
{
try
{
ServerSocket sock = new ServerSocket(1350);
while(true)
{
// open socket
Socket client = sock.accept();
PrintWriter printout = new PrintWriter(client.getOutputStream(),true);
printout.println("Je bent succesvol verbonden met de host");
printout.println("Geef een hostnaam op waarvan je het IP-adres wilt achterhalen:");
//get input from client
InputStream in = client.getInputStream();
BufferedReader bufin = new BufferedReader(new InputStreamReader(System.in));
/*
Thread t = new Thread();
t.start();
*/
String host = "";
Scanner sc = new Scanner(System.in);
System.out.println("Typ de host die u wilt resolven: ");
host = sc.nextLine();
try
{
InetAddress ia = InetAddress.getByName(host);
System.out.println(ia);
}
catch(UnknownHostException uhe)
{
System.out.println(uhe.toString());
}catch (IOException e) {
System.err.println("IOException: " + e);
}
client.close();
}
}catch(IOException ioe)
{
System.err.println(ioe);
}
}
/*
public void run() {
String host = "";
Scanner sc = new Scanner(System.in);
System.out.println("Typ de host die u wilt resolven: ");
host = sc.nextLine();
try
{
InetAddress ia = InetAddress.getByName(host);
System.out.println(ia);
}
catch(UnknownHostException uhe)
{
System.out.println(uhe.toString());
}catch (IOException e) {
System.err.println("IOException: " + e);
}
}
*/
}
Your server don't handle client requests. It wait for new client (socket.accept) and read default system input (System.in) not a socket, and after just close client connection.
it look like:
public static void main(String[] args) throws IOException {
while (true) {
Scanner sc = new Scanner(System.in);
System.out.println("Typ de host die u wilt resolven: ");
String host = sc.nextLine();
try {
InetAddress ia = InetAddress.getByName(host);
System.out.println(ia);
} catch (UnknownHostException uhe) {
System.out.println(uhe.toString());
}
}
}
At the client side you should read address from console, write it to socket (send request), then read data from socket (take response) and out to console;
At the server side you must accept client connection (socket.accept), read data from socket (take request), handle it (InetAddress.getByName(host)) and send response back to the client socket.
so I am having an issue with reading input from a client. It works completely fine whenever I am using my if statements without the while statements wrapped around it in the server class. Could anybody point me to why this may be failing?
Server class:
import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) throws Exception
{
Server myServer = new Server();
myServer.run();
}
public void run() throws Exception
{
//Initializes the port the serverSocket will be on
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("The Server is waiting for a client on port 9999");
//Accepts the connection for the client socket
Socket socket = serverSocket.accept();
InputStreamReader ir = new InputStreamReader(socket.getInputStream());
BufferedReader br = new BufferedReader(ir);
String message = br.readLine();
//Confirms that the message was received
System.out.println(message);
//When this while is here. The match fails and it goes to the else statement.
//Without the while statement it will work and print "Received our hello message."
//when the client says HELLO.
while(message != null)
{
if(message.equals("HELLO"))
{
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println("Received our hello message.");
}
else
{
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println("Did not receive your hello message");
}
}
}
}
Client class:
import java.io.*;
import java.net.*;
import java.util.*;
public class Client {
public static void main(String[] args) throws Exception
{
Client myClient = new Client();
myClient.run();
}
public void run() throws Exception
{
Socket clientSocket = new Socket("localhost", 9999);
//Sends message to the server
PrintStream ps = new PrintStream(clientSocket.getOutputStream());
Scanner scan = new Scanner(System.in);
String cMessage = scan.nextLine();
ps.println(cMessage);
//Reads and displays response from server
InputStreamReader ir = new InputStreamReader(clientSocket.getInputStream());
BufferedReader br = new BufferedReader(ir);
String message = br.readLine();
System.out.println(message);
}
}
You're never modifying message inside the while loop so you have an infinite loop.
Try
while((message = br.readLine()) != null)
You only loops at the Server side, while u forgot to loop at the Client side, I did a quick fix for you, and also help you closed your connections.
Server.java
import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) throws Exception
{
Server myServer = new Server();
myServer.run();
}
public void run() throws Exception
{
//Initializes the port the serverSocket will be on
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("The Server is waiting for a client on port 9999");
//Accepts the connection for the client socket
Socket socket = serverSocket.accept();
InputStreamReader ir = new InputStreamReader(socket.getInputStream());
BufferedReader br = new BufferedReader(ir);
String message;
//= br.readLine();
//Confirms that the message was received
//When this while is here. The match fails and it goes to the else statement.
//Without the while statement it will work and print "Received our hello message."
//when the client says HELLO.
PrintStream ps = new PrintStream(socket.getOutputStream());
while((message =br.readLine())!=null)
{
System.out.println(message);
if(message.equals("HELLO"))
{
ps.println("Received our hello message.");
}
if(message.equals("END"))
{
ps.println("Client ended the connection");
break;
}
else
{
ps.println("Did not receive your hello message");
}
}
ps.close();
br.close();
ir.close();
serverSocket.close();
}
}
Client.java
import java.io.*;
import java.net.*;
import java.util.*;
public class Client {
public static void main(String[] args) throws Exception
{
Client myClient = new Client();
myClient.run();
}
public void run() throws Exception
{
Socket clientSocket = new Socket("localhost", 9999);
//Sends message to the server
PrintStream ps = new PrintStream(clientSocket.getOutputStream());
Scanner scan = new Scanner(System.in);
String cMessage ="";
InputStreamReader ir = new InputStreamReader(clientSocket.getInputStream());
BufferedReader br = new BufferedReader(ir);
while(!(cMessage.trim().equals("END"))){
cMessage = scan.nextLine();
ps.println(cMessage);
//Reads and displays response from server
String message = br.readLine().trim();
System.out.println(message);
}
br.close();
ir.close();
scan.close();
ps.close();
clientSocket.close();
}
}
Your code is working just fine for sending one 'HELLO' message.
However, like ^Tyler pointed out, If you want to keep sending messages you need to move 'while((message = br.readLine()) != null)' in the while loop.
Using a loop like you are...
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
sleep(in);
if(!in.ready()){
break;
}
}
There is a cheater way that I figured out.
private static void sleep(BufferedReader in) throws IOException {
long time = System.currentTimeMillis();
while(System.currentTimeMillis()-time < 1000){
if(in.ready()){
break;
}
}
}
This might be sloppy, but if you make a sleep method that waits an amount of time and just keep checking if the BufferedReader is "ready." If it is, you can break out, but then when you come out check again. -- Maybe you could just return a boolean instead of checking twice, but the concept is there.
I am trying to launch server and client thread on the same process, but seems like the server thread is blocking the client thread (or vice versa). I'm not allowed to use any global variable between those threads(like semaphore or mutex, since the client and the server thread are launched by upper-class that I don't have the access of).
I found a similar question here , but it still use two different process (two main function).
Here is a sample of my code
The server code:
public class MyServer implements Runnable{
ServerSocket server;
Socket client;
PrintWriter out;
BufferedReader in;
public MyServer() throws IOException{
server = new ServerSocket(15243, 0, InetAddress.getByName("localhost"));
}
#Override
public void run() {
while(true){
try {
ArrayList<String> toSend = new ArrayList<String>();
System.out.println("I'll wait for the client");
client = server.accept();
out = new PrintWriter(client.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String inputLine;
while((inputLine = in.readLine()) != null){
toSend.add("answering : "+inputLine);
}
for(String resp : toSend){
out.println(resp);
}
client.close();
out.close();
in.close();
} catch (IOException ex) {
}
}
}
}
And the client code:
public class MyClient implements Runnable{
Socket socket;
PrintWriter out;
BufferedReader in;
public MyClient(){
}
#Override
public void run() {
int nbrTry = 0;
while(true){
try {
System.out.println("try number "+nbrTry);
socket = new Socket(InetAddress.getByName("localhost"), 15243);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out.println("Hello "+nbrTry+" !! ");
String inputLine;
while((inputLine = in.readLine()) != null){
System.out.println(inputLine);
}
nbrTry++;
} catch (UnknownHostException ex) {
} catch (IOException ex) {
}
}
}
}
And the supposed upper-class launching those thread:
public class TestIt {
public static void main(String[] argv) throws IOException{
MyServer server = new MyServer();
MyClient client = new MyClient();
(new Thread(server)).start();
(new Thread(client)).start();
}
}
It gives me as output:
I'll wait for the client
Try number 0
And it stuck here. What should I do to keep both server and client code running?
Thank you.
I'll be willing to take up your questions but basically you need to think through your logic a bit more carefully.
MyServer.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class MyServer implements Runnable {
ServerSocket server;
public MyServer() throws IOException {
server = new ServerSocket(15243, 0, InetAddress.getByName("localhost"));
}
#Override
public void run() {
while (true) {
try {
// Get a client.
Socket client = server.accept();
// Write to client to tell him you are waiting.
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
out.println("[Server] I'll wait for the client");
// Let user know something is happening.
System.out.println("[Server] I'll wait for the client");
// Read from client.
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String inputLine = in.readLine();
// Write answer back to client.
out.println("[Server] Answering : " + inputLine);
// Let user know what it sent to client.
System.out.println("[Server] Answering : " + inputLine);
in.close();
out.close();
client.close();
} catch (Exception e) {
}
}
}
}
MyClient.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class MyClient implements Runnable {
Socket socket;
PrintWriter out;
BufferedReader in;
public MyClient() throws UnknownHostException, IOException {
}
#Override
public void run() {
int nbrTry = 0;
while (true) {
try {
// Get a socket
socket = new Socket(InetAddress.getByName("localhost"), 15243);
// Wait till you can read from socket.
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String inputLine = in.readLine();
//inputLine contains the text '[Server] I'll wait for the client'. means that server is waiting for us and we should respond.
// Write to socket
out = new PrintWriter(socket.getOutputStream(), true);
out.println("[Client] Hello " + nbrTry + " !! ");
// Let user know you wrote to socket
System.out.println("[Client] Hello " + nbrTry++ + " !! ");
} catch (UnknownHostException ex) {
} catch (IOException ex) {
}
}
}
}
TestIt.java
import java.io.IOException;
public class TestIt {
public static void main(String[] argv) throws IOException {
MyServer server = new MyServer();
MyClient client = new MyClient();
(new Thread(server)).start();
(new Thread(client)).start();
}
}
Your client sends a string, then reads until the stream is exhausted:
while((inputLine = in.readLine()) != null){
BufferedReader.readLine() only returns null at the end of the stream, as I recall. On a stream, it will block until input is available
Your server receives until the stream is exhausted, then sends back its response.
After sending one line, you now have:
Your client waiting for a response.
Your server still waiting for more data from the client. But it doesn't send anything back until the end of the stream from the client (which never happens because the client is waiting for your response).
Here is the server code
package echoserver;
import java.net.*;
import java.io.*;
public class EchoServer {
public static void main(String[] args) {
try {
//establish server socket
ServerSocket s = new ServerSocket(1981);
//Thread client connectionsincoming
while (true) {
//wait for incoming connection
Socket incoming = s.accept();
Runnable r = new ThreadedEchoHandler(incoming);
Thread t = new Thread(r);
t.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
package echoserver;
import java.net.*;
import java.util.*;
import java.io.*;
class ThreadedEchoHandler implements Runnable {
public ThreadedEchoHandler(Socket i) {
//initializing socket
incoming = i;
}
public void run() {
try {
try {
//recieve input stream from socket
InputStream inStream = incoming.getInputStream();
//recieve output stream from socket
OutputStream outStream = incoming.getOutputStream();
//Create a scanner from input stream
Scanner scan = new Scanner(inStream);
//Create printer writer from output stream and enabled auto flushing
PrintWriter out = new PrintWriter(outStream, true);
//prompt users on how to exit program soon as a long in into the server
out.println("Enter BYE to exit");
boolean done = false;
//while done is not true and scanner has next line loop
while (!done && scan.hasNextLine()) {
//reading text that came in from the socket
String line = scan.nextLine();
//On the server print the ip address of where the text is coming from and the text they typed
System.out.println("Recieved from " + incoming.getInetAddress().getHostAddress() + ": " + line);
//Echo back the text the client typed to the client
out.println("Echo: " + line);
//if they type BYE in caps terminate there connection and I also trimmed whitespaces
if (line.trim().equals("BYE")) {
done = true;
}
}
} //finally close the socket connection
finally {
incoming.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
private Socket incoming;
}
and here is the code for client
package client;
import java.net.*;
import java.io.*;
public class Client {
public static void main(String[] args) throws IOException {
PrintWriter out = null;
try {
Socket s = new Socket(InetAddress.getLocalHost(), 1981);
System.out.println("Connected to server on port 1981");
out = new PrintWriter(s.getOutputStream());
out.println("Hello");
s.close();
} catch (Exception ex) {
System.err.println(ex.getMessage());
}
}
}
Socktes are getting created successfully but when control goes to t.start() method call it is not calling run() method of ThreadedEchoHandler class.
Why is this happening? any idea?
The client writes "Hello" to the PrintWriter. So far, so good.
You may expect that the PrintWriter sends this text directly to the socket, but it doesn't. The documentation from the PrintWriter(OutputStream) constructor says that it creates a PrintWriter without automatic line flushing. This means that you have to call out.flush() whenever you want something to be actually sent.
Until you call out.flush() the text only exists in some internal buffer, and the server will not be able to see it.
My guess would be that the acept statement is blocking forever because no client is connecting to the server. You could wrap accept() in prints to prove or disprove.