Reading and Writing to Server - java

Objective: send data to server and have server return something back and to print what the server sends back
Problem: If I close the out stream then it will send the data to the server but my input stream won't work and I can't receive what the server tries to give me. If I use flush() to send data to server the server never receives the data. I have been stuck on this for literally 3 hours. How do you do read and Write at the same time.
Client.java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
class Client {
public static void main(String args[]) {
String data = "head";
try {
Socket skt = new Socket("server", 5050);
PrintWriter out = new PrintWriter(skt.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(skt.getInputStream()));
out.print(data);
out.close();
System.out.println("Sent data");
while (!in.ready()) {
}
String input = in.readLine();
System.out.println(input);
out.close();
in.close();
skt.close();
} catch (Exception e) {
System.out.print("Whoops! It didn't work!\n" +e.toString());
}
}
}
Server.java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.PrintWriter;
class Server {
public static void main(String args[]) {
String data;
String input;
try {
ServerSocket srvr = new ServerSocket(5050);
Socket skt = srvr.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(
skt.getInputStream()));
PrintWriter out = new PrintWriter(skt.getOutputStream(), true);
// /////Waits for message from client/////////
while (!in.ready()) {
}
// ///////////////////////////////////////////
input = in.readLine(); // Read the message
System.out.println("Received String input: " + input);
// Send output to client
System.out.println("After output");
if (input.equals("head"))
data = "haha";
else
data = "Wtf did you send me";
Thread.sleep(2000);
out.print(data);
// ///////////////////
System.out.println("Sent data: " + data);
in.close();
out.close();
skt.close();
srvr.close();
} catch (Exception e) {
System.out.print("Whoops! It didn't work!\n");
}
}
}

In your client you have:
out.print(data);
out.close();
and in your server you have:
input = in.readLine();
Client send message without new line character - that's why in.ready() is true. What's more - it closes PrintWriter instead of flushing (you are also closing stream at the end of program). If you change that lines to:
out.println(data); // sends message with new line character
out.flush(); // unnecessary
Client sends a message. The same thing is when Server sends message - you use print instead of println but Client reads using readLine that reads until new line character, or to be more precise (BufferedReader|readLine()):
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.
One more thing - you are connecting to the server using "server" hostname. For my tests I changed it to "localhost". Maybe there is other mistake?

Related

Java network client sends only one message

I am learning Java and I'm writing an example client - server application.
The sokcket connection is fine, everything works well until the second message from the client app. It does not reach the server. If I start another client it also succeed at the first message, and fails at the second.
Anyone has an idea? Thanks in advance!
Server code:
package networking;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
private static Socket socket;
public static void main(String[] args) {
try {
int port = 25000;
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("Server Started and listening to the port 25000");
//Server is running always. This is done using this while(true) loop
while (true) {
//Reading the message from the client
socket = serverSocket.accept();
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String incomingMessage = br.readLine();
System.out.println("((( " + incomingMessage);
String returnMessage = incomingMessage;
//Sending the response back to the client.
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write(returnMessage + "\n");
bw.flush();
System.out.println("))) " + returnMessage);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (Exception e) {
}
}
}
}
And the client
package networking;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Client {
private static Socket socket;
public static void main(String args[]) {
try {
String host = "localhost";
int port = 25000;
InetAddress address = InetAddress.getByName(host);
socket = new Socket(address, port);
//Send the message to the server
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String message = "";
/*
while(!message.equals("q")) {
System.out.print("Message: ");
message = console.readLine();
bw.write(message + "\n");
bw.flush();
System.out.println("))) " + message);
//Get the return message from the server
String incomingMessage = br.readLine();
System.out.println("((( " + incomingMessage);
}
*/
for (int i = 0; i < 10; i++) {
bw.write(i + "\n");
bw.flush();
System.out.println("))) " + i);
String incomingMessage = br.readLine();
System.out.println("((( " + incomingMessage);
}
} catch (Exception exception) {
exception.printStackTrace();
} finally {
//Closing the socket
try {
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Your while is misplaced in your server code, and in fact you need 2 while loops:
one for accepting new clients
one for manage several messages by client
In pseudo code it gives you:
while (true):
accept new client
while (client connected):
read message from client
write back message to client
close client socket
If you want to use threads, then it's the inner while loop task which you have to delegate to a new thread.
Note: accept is blocking until a new client comes. That why you could send only one message by client.
Your server is not set up to handle this. You are reading one line, then discarding the connection for the GC, without closing it. The server, reading one line, then ignores all other lines and starts listening for the next connection.
Also, consider using threads.

while loop only stops at first loop then continues to run indefinitely

The goal of this practice program is simply to allow the client to continuously send strings of messages that the user inputs via typing and hitting enter key and prints it to console. The first time around , String messageFromClient = in.readLine(); in Server.java seems to block (Debugger won't let me step out). However after sending it a message like "hello", it continuously runs without blocking anymore.
I've been searching this up for a couple of hours but I guess I'm just not looking at the right places for the solution.
This link Java InputStream blocking read is probably the closest thing I've found that might help me.
Client.java
import java.io.*;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.*;
import java.net.InetAddress;
import java.util.Scanner;
public class Client {
static Socket connectionToServer;
public static void main(String[] args) {
try{
connectionToServer = new Socket("192.168.1.66", 6969);
InetAddress inetAddress = connectionToServer.getInetAddress();
System.out.print(
"Connection successful" +
"Connected to " + inetAddress.getHostAddress() +
"at " + inetAddress.getHostName() + "\n"
);
while(true) {
String input = System.console().readLine();
OutputStreamWriter dOut = new OutputStreamWriter(connectionToServer.getOutputStream());
dOut.write(input, 0, input.length());
//dOut.flush();
dOut.close();
}
} catch (IOException exception){
System.out.print("Failed to create socket");
}
}
}
Server.java
import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) {
ServerSocket serverSocket;
try {
serverSocket = new ServerSocket(6969);
System.out.print("Server is up and running \n");
} catch (IOException exception){
serverSocket = null;
System.out.print("Cannot create ServerSocket");
}
while (true){
try {
System.out.print("Waiting from client.");
Socket socket = serverSocket.accept();
Thread newClientSocket = new Thread(new ServerThread(socket));
newClientSocket.start();
System.out.print("New thread created");
} catch (IOException exception){
System.out.print("Failed to create socket");
}
}
}
}
////////////////////////////////////////////////////////////
class ServerThread implements Runnable{
private Socket socket;
//constructor
ServerThread(Socket socket){
System.out.print("I am a new thread");
this.socket = socket;
}
public void run(){
while(true){
try{
System.out.print("Waiting for input.");
InputStreamReader inputStreamReader = new InputStreamReader(socket.getInputStream());
BufferedReader in = new BufferedReader(inputStreamReader);
String messageFromClient = in.readLine();
System.out.print(messageFromClient);
} catch (IOException exception) {
System.out.print(exception);
break;
}
}
}
}
You shouldn't construct a new BufferedReader for each loop iteration, since a BufferedReader will try to fill its buffer completely and possibly read beyond the end of the first line - and that data will be lost, since you're constructing a new BufferedReader after reading only the first line from it.
Move the construction of the BufferedReader out of the loop, that should help you. Also, make sure that you close the socket when you're done with it.
public void run() {
try {
try {
InputStreamReader inputStreamReader = new InputStreamReader(socket.getInputStream());
BufferedReader in = new BufferedReader(inputStreamReader);
while (true) {
System.out.print("Waiting for input.");
String messageFromClient = in.readLine();
System.out.print(messageFromClient);
}
} finally {
socket.close();
}
} catch (IOException exception) {
System.out.print(exception);
// TODO: handle exception
}
}
On the sending side, you shouldn't close the socket's OutputStream for every line, because once you close it, you can't use it anymore. And you should send a newline to the server after the string, as the Console.readLine() method doesn't include it in its return value.
OutputStreamWriter dOut = new OutputStreamWriter(connectionToServer.getOutputStream());
while(true) {
String input = System.console().readLine() + "\n";
dOut.write(input, 0, input.length());
}
dOut.close();
Console.readLine() does not include terminating characters. BufferedReader.readLine() blocks until it gets a terminating newline character
Change this:
String input = System.console().readLine();
To this:
String input = System.console().readLine() + System.lineSeparator();

Java socket will send but then not receive response

I am currently learning Java and am playing around with socket programming.
My goal is to implement request-response communication like HTTP. I can get one way communication from the client to the server. But when I program the client to listen for a response it causes the server to not print out the request.
I've googled the issue and most posts mention using the flush() method, which I have tried. Anyone have any thoughts?
Here is the client code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
class Client {
public static void main(String args[]) throws IOException {
// Get the port number from the first command line argument
int port_number;
if(args.length == 0) {
port_number = 80;
} else {
port_number = Integer.parseInt(args[0]);
}
try (
// Create a socket
Socket socket = new Socket("localhost", port_number);
// Input reader
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream())
);
// Output writer
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
) {
System.out.println("Sending request");
out.print("Foo");
out.flush();
System.out.println("Sending Complete");
// If this next section is commented out then the server prints the message
StringBuilder message = new StringBuilder();
int data;
while((data = in.read()) != -1) {
message.append((char) data);
}
System.out.print(message);
}
}
}
and here is my server code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String args[]) throws IOException {
// Get the port number from the first command line argument
int portNumber = Integer.parseInt(args[0]);
System.out.println("Listening on port " + portNumber);
ServerSocket serverSocket = new ServerSocket(portNumber);
while (true) {
try (
Socket socket = serverSocket.accept();
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream())
);
){
StringBuilder message = new StringBuilder();
int data;
while((data = in.read()) != -1) {
message.append((char) data);
}
System.out.println(message);
out.print("Bar");
}
}
}
}
This is because your sever currently loop until read() returns -1 which never happens in your case so he never reaches the part of the code where he is supposed to send Bar, you need a specific marker to indicate the end of your message so for example here you can send data line by line, for this proceed as next:
Client side:
System.out.println("Sending request");
// Send a line to the server
out.println("Foo");
out.flush();
System.out.println("Sending Complete");
// Read a line sent by the server
System.out.print(in.readLine());
Output:
Sending request
Sending Complete
Bar
Server side:
// Print the line sent by the client
System.out.println(in.readLine());
// Send a message to the client
out.println("Bar");
Output:
Listening on port 9999
Foo

Java client-socket:Cannot receive messages from server to client

So there this problem that has been giving me headaches for days now.I am making a multi-user chat application.My design is as follows:
1.There is a login window.
2.As soon as the details are entered, the client-side chat window opens.
3.Now the user starts typing.
4.As soon as he hits enter or clicks on the send button,the message is sent to the server.
5.The server sends it to all clients, including the one that send it the original message.
The problem:I am unable to receive any messages from the server to the client.
Here is my server class:
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class Server implements Runnable {
static InetAddress address;
static ArrayList<Integer> clients=new ArrayList<Integer>();
static ArrayList<Socket> socs=new ArrayList<>();
static String message="";
static DataOutputStream toClient;
static ServerSocket socket;
static Socket socketNew;
static boolean running=false;
public static void main(String[] args) throws IOException
{
socket=new ServerSocket(8000);
System.out.println("Server started on port 8000");
running=true;
while(true)
{
socketNew=socket.accept();
socs.add(socketNew);
address=socketNew.getInetAddress();
System.out.println("connected to client at address: "+address);
Server server=new Server();
new Thread(server).start();
}
}
public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(socketNew.getInputStream()));
String message;
PrintWriter out;
while ((message = br.readLine()) != null) {
System.out.println(message);
for (Socket s : socs) // sending the above msg. to all clients
{
out = new PrintWriter(s.getOutputStream(), true);
out.write(message);
out.flush();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
And here is the receive_message function in the client class.Note that this method,I've run on a separate thread that starts as soon as the user logs-in.
public void receive_data()
{while(true)
{
try {
BufferedReader in;
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(in.readLine()!=null)
{
System.out.println(in.readLine());
console(in.readLine());
}
}
catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
Any suggestions?Thanks for your time. :-)
You are writing messages without a line ending, while your client is waiting for a line ending character in the readLine loop. By placing out.write('\n') in your server send loop, it will also send a newline character.
Example:
for (Socket s : socs) {
out = new PrintWriter(s.getOutputStream(), true);
out.write(message);
out.write('\n'); // added this line
out.flush();
}

http server and client implementing head and get method

I'm trying to make a simple http client server using java. It will show the client's request as well as the server's response. For example server will send back
HTTP/1.0 200 OK
Connection: Close. etc.
Previously i had a echo client server. Now I've turned my echo server to act as a http server. I've tried Goggling about how to implement the head and get with the client but i noticed usually all of the example used apache framework. Is there a way to implement these method without apache framework.
My echo client which i'm trying to convert into a http client:
import java.io.*;
import java.net.*;
public class Ec1
{
public static void main(String[] args)
{
try
{
Socket s = new Socket("127.0.0.1", 80);
BufferedReader r = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter w = new PrintWriter(s.getOutputStream(), true);
BufferedReader con = new BufferedReader(new InputStreamReader(System.in));
String line;
do
{
line = r.readLine();
if ( line != null )
System.out.println(line);
line = con.readLine();
w.println(line);
}
while ( !line.trim().equals("bye") );
}
catch (Exception err)
{
System.err.println(err);
}
}
}
My Http server:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Echo
{
protected void start() {
ServerSocket s;
System.out.println("Webserver starting up on port 80");
try {
// create the main server socket
s = new ServerSocket(80);
} catch (Exception e) {
System.out.println("Error: " + e);
return;
}
Socket clientSocket = null;
System.out.println ("Waiting for connection.....");
try {
clientSocket = s.accept();
System.out.println("Connection, sending data.");
BufferedReader in = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream());
String str = ".";
while (!str.equals(""))
str = in.readLine();
out.println("HTTP/1.0 200 OK");
out.println("Content-Type: text/html");
out.println("Server: Bot");
out.println("");
out.println("<H1>Welcome to the Ultra Mini-WebServer</H2>");
out.flush();
clientSocket.close();
s.close();
} catch (Exception e) {
System.out.println("Error: " + e);
}
}
public static void main(String args[]) {
WebServer ws = new WebServer();
ws.start();
}
}
Yes, there is, just interpret your request you're getting from the client.
From the following code (in HttpServer), parse:
String str = ".";
while (!str.equals("")) {
str = in.readLine();
if (str.startsWith("HEAD")) {
//Head execution here...
}
}
Etc...
Everybody uses some kind of library or framework for the client and/or the server side because HTTP is somewhat complex and there is no need to reinvent every wheel. However, it is quite possible to write your own implementation by starting directly from the RFCs for HTTP.

Categories