I am trying to build a simple request/response server.
Client send a message to Server. Then, the server response a message to client.
Server-side Code
package com.techoffice.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import javax.net.ServerSocketFactory;
public class TcpServerAppl {
static int port = 1010;
static ServerSocket serverSocket;
static {
try {
serverSocket = ServerSocketFactory.getDefault().createServerSocket(port);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
System.out.println("Server is running on " + port);
while(true){
Socket socket = null;
try{
socket = serverSocket.accept();
System.out.println("Someone is connecting to the server");
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
PrintWriter printWriter = new PrintWriter(os);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));
// read message from client
String line = bufferedReader.readLine();
while(line != null && line.length() > 0){
System.out.println(line);
line = bufferedReader.readLine();
}
// reader.close();
// send message to client
System.out.println("Server starts sending message to client");
printWriter.println("This is a message sent from server");
printWriter.flush();
// printWriter.close();
} catch(Exception e){
System.err.println(e.getMessage());
} finally {
if (socket != null){
try {
socket.close();
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
}
}
}
}
Client-side code
package com.techoffice.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.net.SocketFactory;
public class TcpClientAppl {
public static void main(String[] args) throws UnknownHostException, IOException{
// start socket connection
Socket socket = SocketFactory.getDefault().createSocket("localhost", 1010);
PrintWriter printWriter = new PrintWriter(socket.getOutputStream());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// send message to server
printWriter.println("Send Message From Client" );
printWriter.flush();
// printWriter.close();
// read message from server
System.out.println("Client starts reading from Server");
String line = bufferedReader.readLine();
while(line != null && line.length() > 0){
System.out.println(line);
line = bufferedReader.readLine();
}
// bufferedReader.close();
// close scoket connection
socket.close();
}
}
The Server is blocked at the Buffered Reader. However, if I tried to close the Buffered Reader by closing in Print Writer in Client, the Client throw an exception of "Connection Closed".
It is known that closing in PrintWriter or BufferedReader would close the socket connection.
Update
Specifying a End of Request/Message would be one of solution. But in this case, I would not want to have an End of Request. I just want to have response for a request no matter no many line is in the request.
The client throw an exception of 'connection closed'
No it doesn't. If you uncomment the printWriter.close() line it will throw an exception 'socket closed'.
But to your real problem. The server reads lines until end of stream before it sends anything: end of stream will never occur until the peer closes the connection; and the peer isn't closing the connection, except as above; so it will never send anything and just stay blocked in readLine(); so the client will block forever in readLine() too.
As this is evidently an echo server, it should echo every line as it is received.
Question is missing exception thrown by client side. Maybe try to close everything (reader,writer) on server-side after your communication is done. BTW. you don't need to call flush before calling close. Also you can use try-catch-withResources with socket on server side
Related
I am new to Java just started yesterday. I wrote a very simple client server java code. Client sends a message to server. The Server should display that message. And the Server should send a message to client after receiving the message. The client should display the message sent by server.
Server Code,
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.OutputStreamWriter;
import java.io.BufferedWriter;
import java.net.Socket;
import java.net.ServerSocket;
public class CustomServer{
public static void main(String[] args){
final int SERVER_PORT_NUMBER = 8081;
try{
ServerSocket serverObj = new ServerSocket(SERVER_PORT_NUMBER);
Socket clientSocketObj = serverObj.accept();
BufferedReader clientInputStream = new BufferedReader(new InputStreamReader(clientSocketObj.getInputStream()));
BufferedWriter clientOutputStream = new BufferedWriter(new OutputStreamWriter(clientSocketObj.getOutputStream()));
if(clientSocketObj != null){
System.out.println("Client Connected to Server!");
// Recieve Message from Client
System.out.println("MESSAGE FROM CLIENT");
System.out.println(clientInputStream.readLine());
// Send Message to Client
clientOutputStream.write("SERVER: Hello Client!");
// Close Streams
clientOutputStream.close();
clientInputStream.close();
}
serverObj.close();
}
catch(Exception e){
System.out.println(e);
}
}
}
Client,
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;
public class CustomClient{
public static void main(String[] args){
final String HOST_NAME = "127.0.0.1";
final int SERVER_PORT_NUMBER = 8081;
try{
Socket clientSocket = new Socket(HOST_NAME, SERVER_PORT_NUMBER);
BufferedWriter clientOutputStream = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
BufferedReader clientInputStream = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
System.out.println("Connecting....");
if(clientSocket != null){
System.out.println("Connected to Server!");
// Send message to Server
clientOutputStream.write("CLIENT: HELLO SERVER");
// Recieve message from Server
System.out.println("MESSAGE FROM SERVER");
System.out.println(clientInputStream.readLine());
// Close Streams
clientInputStream.close();
clientOutputStream.close();
}
clientSocket.close();
}
catch(Exception e){
System.out.println(e);
}
}
}
Neither the Server or Client receive the message. Stuck in some loop. Anyone know why?
Start by having a read of the BufferedReader's JavaDocs, which state
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
BufferedWriter#write is not sending this, so the reader is still waiting.
A simply solution might be to use BufferedWriter#newLine after the write
And don't forget to flush the buffer when you're finished writing to it!
You may also want to take a look at try-with-resources which will provide a better resource management solution
CustomClient
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
public class CustomClient {
public static void main(String[] args) {
final String HOST_NAME = "127.0.0.1";
final int SERVER_PORT_NUMBER = 8081;
try (Socket clientSocket = new Socket(HOST_NAME, SERVER_PORT_NUMBER)) {
try (BufferedWriter clientOutputStream = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
BufferedReader clientInputStream = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))) {
System.out.println("Connecting....");
System.out.println("Connected to Server!");
// Send message to Server
clientOutputStream.write("CLIENT: HELLO SERVER");
clientOutputStream.newLine();
clientOutputStream.flush();
// Recieve message from Server
System.out.println("MESSAGE FROM SERVER");
System.out.println(clientInputStream.readLine());
}
} catch (Exception e) {
System.out.println(e);
}
}
}
CustomServer
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class CustomServer {
public static void main(String[] args) {
final int SERVER_PORT_NUMBER = 8081;
try (ServerSocket serverObj = new ServerSocket(SERVER_PORT_NUMBER)) {
try (Socket clientSocketObj = serverObj.accept()) {
try (BufferedReader clientInputStream = new BufferedReader(new InputStreamReader(clientSocketObj.getInputStream()));
BufferedWriter clientOutputStream = new BufferedWriter(new OutputStreamWriter(clientSocketObj.getOutputStream()))) {
System.out.println("Client Connected to Server!");
// Recieve Message from Client
System.out.println("MESSAGE FROM CLIENT");
System.out.println(clientInputStream.readLine());
// Send Message to Client
clientOutputStream.write("SERVER: Hello Client!");
clientOutputStream.newLine();
clientOutputStream.flush();
}
}
} catch (Exception e) {
System.out.println(e);
}
}
}
This is the code for my server, its supposed to take an input from the user, print it into console, then send it back to the user.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class DateServer {
public static void main(String[] args) throws Exception {
ServerSocket listener = new ServerSocket(10219);
Socket s = listener.accept();
InputStreamReader in = new InputStreamReader(s.getInputStream());
BufferedReader input = new BufferedReader(in);
PrintWriter out = new PrintWriter(s.getOutputStream());
out.println("connected");
out.flush();
System.out.println("connected");
String test;
while (true) {
try {
test = input.readLine();
System.out.println(test);
out.println(test + " is what I recieved");
out.flush();
} catch(Exception X) {System.out.println(X);}
}
}
}
This is the code for the client:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.*;
public class DateClient {
public static Scanner keyboard = new Scanner(System.in);
public static void main(String[] args) throws Exception {
System.out.println("Enter IP Address of a machine that is");
System.out.println("running the date service on port 10219:");
String serverAddress = keyboard.next();
Socket s = new Socket(serverAddress, 10219);
BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter out = new PrintWriter(s.getOutputStream());
System.out.println(input.readLine());
while(true){
try{
System.out.println(input.readLine());
out.println(keyboard.next());
out.flush();
} catch(Exception X){System.out.println(X);}
}
}
}
This was designed to work across a LAN network. I have no idea why it doesn't work, all that happens is the client will get the message "connected" and nothing else will happen, no matter what is typed into the client end. I'm a noob when it comes to java, but after a bunch of googling and searching through the java libraries, I can't seem to make it work. What did I do wrong?
You send one line from the server to the client, but in your client you wait for two lines before accepting user input to be sent to the server.
Bearing in mind that input.readLine() will block until data is received, can you spot the deadlock here:
Server:
out.println("connected");
while (true) {
try {
input.readLine();
}
}
Client:
input.readLine();
while(true) {
try {
input.readLine();
out.println(keyboard.next());
}
}
(extraneous code trimmed away to show just the problematic sequence of statements)
Both your client and server mutually wait for each other trying to do input.readLine().
This can be easily seen if you remove server's out.println("connected") and its corresponding client's first input.readLine().
On the client, you should probably write first and only then read the response. Try reordering the following lines:
System.out.println(input.readLine());
out.println(keyboard.next());
out.flush();
to get
out.println(keyboard.next());
out.flush();
System.out.println(input.readLine());
In the client, try changing
PrintWriter out = new PrintWriter(s.getOutputStream());
System.out.println(input.readLine());
while(true){
try{
System.out.println(input.readLine());
out.println(keyboard.next());
out.flush();
} catch(Exception X){System.out.println(X);}
}
to
PrintWriter out = new PrintWriter(s.getOutputStream());
while(true){
try{
System.out.println(input.readLine());
out.println(keyboard.nextLine());
out.flush();
} catch(Exception X){System.out.println(X);}
}
Your client is trying to read two lines, but your server sends just one, then polls for input, so both are locked. Also, sinc your server is reading line-by-line, your client should be sending data line-by-line.
I created a java application in Eclipse to connect Plant Simulation via Socket. My first step is just sending and receiving messages "Hello" between plant simulation (PS) and my java application. It worked, but I thought it was strange.
Java application is server. PS is client.
I run "ServerJava" first time. When I active "MyClientSocket" in PS, message "Hallo Plant Simulation" is received in PS. Then I run method "m_sendMessage" in PS to send message "Hallo Java" to ServerJava. It is sent to ServerJava, but its not printed in console. If I deactive "MyClientSocket" to disconnect, its printed in console.
How can message be printed immediately, when I run the method "m_sendMessage" in PS?
My codes:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerJava {
public static void main(String[] args) {
ServerSocket listener = null;
String line = null;
Socket clientSocket = null;
// ServerSocket with Port 30005
try {
listener = new ServerSocket(30005);
} catch (IOException e) {
System.out.println(e);
System.exit(1);
}
try {
System.out.println("Server is waiting to accept user...");
clientSocket = listener.accept();
System.out.println("Accept a client!");
BufferedReader is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
BufferedWriter os = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
while (true) {
// Message to client: Hello Plant Simulation
os.write("Hello Plant Simulation");
os.flush();
//Message from client: Hello Java
line = is.readLine();
System.out.println(line);
os.close();
}
} catch (IOException e) {
System.out.println(e);
e.printStackTrace();
}
System.out.println("Sever stopped!");
}
}
Code for m_sendMessage
Thank you in Advance for your help.
I recently programmed a simple Java server, and a client to test the server. The server is supposed to receive messages from the client, and send a random substring of the message back. The problem is this: When I send the message using the client program, the server does not respond. Then, when I kill the client program, the server leaps into action, and attempts to send the data back to the client. The server reads the data correctly but starts processing it only when I stop the client program.
This is the client code:
import java.io.*;
import java.net.*;
class ServerTest{
public static void main(String args[]) throws Exception{
Socket clientSocket = new Socket(myIpAdress, 8001);
//Send the message to the server
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
String sendMessage = "randSubstring:StackOverflowIsAwsome";
bw.write(sendMessage);
bw.flush();
System.out.println("Message sent: "+sendMessage);
String message = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())).readLine();
System.out.println("Message received from the server : " +message);
clientSocket.close();
}
}
My server code consists of two classes. This one is the listener:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerListener {
public static void main(String args[]) throws Exception {
String clientSentence;
ServerSocket socket = new ServerSocket(8001);
while(true) {
Socket connectionSocket = socket.accept();
BufferedReader input = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
//DataOutputStream output = new DataOutputStream(connectionSocket.getOutputStream());
clientSentence = input.readLine();
if(clientSentence.startsWith("randSubstring:")){
Thread connection = new Thread(new ServerConnection(connectionSocket, clientSentence));
connection.start();
}
Thread.sleep(300);
}
}
}
This is the thread that will not start until the client is stopped:
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Random;
public class ServerConnection implements Runnable{
private Socket serverConnection;
private String sentence;
public ServerConnection(Socket connection, String clientSentence){
serverConnection = connection;
sentence = clientSentence;
}
#Override
public void run() {
Random r = new Random();
String substring = sentence.substring(0, r.nextInt(sentence.length()));
try {
OutputStream os = serverConnection.getOutputStream();
OutputStream out = new BufferedOutputStream(os);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));
bw.write(substring);
bw.close();
out.close();
os.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I am using a Macintosh with Yosemite. Is this happening because I am trying to run the programs on the same computer, or would the problem occur if the programs were run from different computers? Any help is appreciated.
In the server you do a readLine(..), which means that it will wait for a end-of-line character.
But in your sender code, you just send a string with no line ending.
So either you make sure you also send a end of line char or your server wait's for something else as "delimiter"
You're reading a line but you aren't writing a line. Add a line terminator to the sent message. Otherwise readLine() won't return until the peer closes the connection.
NB The I/O in the try block after the accept should be in the Runnable, not where it is. Don't do I/O in the accept loop.
I have a server which takes a request for a WSDL and sends back the WSDL's XML line by line. I know the request is being received and processed correctly because I have the server printing out the XML to the console as it's writing to the server socket. My problem right now is my client app is supposed to be reading in the xml and then printing out method signatures using the xml. I'm going to use DOM / DocumentBuilder to get the parts of the method signature(s) from the WSDL, but I need to first put the lines read in into a file. How can I do this? Currently I'm trying to do it this way:
//request WSDL from server
System.out.println("Client requesting \"MathServices?wsdl\"...");
socketWriter.write("GET MathServices?wsdl");
socketWriter.close();
//read XML response into file
try {
File wsdlXML = new File("MathServices.xml");
FileOutputStream wsdlXmlWriter = new FileOutputStream(wsdlXML);
String xmlLine;
while((xmlLine = socketReader.readLine()) != null){
wsdlXmlWriter.write(xmlLine.getBytes());
}
} catch (IOException e) {
e.printStackTrace();
}
But am getting this error:
Client requesting "MathServices?wsdl"...
java.net.SocketException: socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
at java.io.InputStreamReader.read(InputStreamReader.java:167)
at java.io.BufferedReader.fill(BufferedReader.java:136)
at java.io.BufferedReader.readLine(BufferedReader.java:299)
at java.io.BufferedReader.readLine(BufferedReader.java:362)
at client.Client.main(Client.java:50)
EDIT: server code
package server;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Scanner;
public class RequestHandler extends Thread {
Object block;
ServerSocket serverSocket;
BufferedReader socketReader;
PrintWriter socketWriter;
public RequestHandler(Object block, ServerSocket serverSocket){
this.block = block;
this.serverSocket = serverSocket;
}
#Override
public void run() {
try{
System.out.println("Waiting for connection...");
Socket clientSocket = serverSocket.accept();
System.out.println("Connection made.");
synchronized(block){
System.out.print("Notifying server thread...");
block.notify();
System.out.println("...done");
System.out.println();
}
System.out.println("Setting up streams...");
socketReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
socketWriter = new PrintWriter(clientSocket.getOutputStream(), true);
System.out.println("Reading request");
String input;
while((input = socketReader.readLine()) != "\n"){
//System.out.println("Input: " +input);
if(input.startsWith("GET")){
System.out.println("GET received.");
getResource(input);
}
}
socketWriter.close();
socketReader.close();
clientSocket.close();
System.out.println("Streams closed.");
}catch(IOException e){
System.out.println("IOException!");
e.printStackTrace();
}
}
public void getResource(String getRequest){
String[] parts = getRequest.split("\\s+");
String filename = parts[1].substring(1);
if(filename.equals("MathServices?wsdl")){
filename = "MathServices.wsdl";
}
System.out.println(filename);
File resource = new File(filename);
sendResponse(resource, 1);
}
public void sendResponse(File resource, int type){
System.out.println(resource.getAbsolutePath());
Scanner fileReader;
try {
fileReader = new Scanner(resource);
while(fileReader.hasNext()){
String line = fileReader.nextLine();
System.out.println(line);
socketWriter.println(line);
}
socketWriter.println("\n");
System.out.println("end of response");
socketWriter.close();
} catch (FileNotFoundException e) {
System.out.println("File not found!");
e.printStackTrace();
}
}
}
It looks like you are closing the Socket before reading from socketReader. You must fully read the results from that object before closing the Socket. Is this all of the code? You could also try adding socketWriter.flush() prior to closing it.
Edit:
I noticed that you are sending a GET request to the server, presumably intending to issue an HTTP GET? If so your request is malformed. Try this:
socketWriter.write("GET /MathServices?wsdl HTTP/1.1\r\n\r\n");
You would probably be better off using java.net.URLConnection or Apache HttpClient for this task.