Server and ServerSocket in one Application: not working - java

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/

Related

How can i get the reply from server TCP in java

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!

Read/write in simple client-server app in Java

I'm new with Java and I'm trying to learn threads and socket. So decide to make simple client-server application following official java tutorial. My idea is simple - server wait for connection, if appears, it makes new thread with new socket, input and output. Client side -> make connection; new thread with socket, input, output and stdIn (to read line and after that send it to the server). But something is wrong (don't have any idea why) with my code. The connection is established, there's no exceptions. Could someone explain why doesn't work and how to fix it? Also could you have any suggestions about the code (probably it's not with best practices and things like that):
Client side:
public class Client {
private BufferedReader reader;
private Socket sock;
private PrintWriter writer;
public static void main(String[] args) {
Client client = new Client();
client.go();
}
public void go() {
setUpNetworking();
}
private void setUpNetworking() {
try{
sock = new Socket("127.0.0.1", 5000);
System.out.println("Network established");
ServerThread serverThread= new ServerThread(sock);
serverThread.start();
System.out.println("Type your message: ");
} catch (IOException e) {
System.out.println("Problem with establishing the network: " + e);
}
}
class ServerThread extends Thread {
Socket socket;
PrintWriter out;
BufferedReader in;
BufferedReader stdIn;
ServerThread(Socket socket) {
this.socket = socket;
try{
out = new PrintWriter(socket.getOutputStream());
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
stdIn = new BufferedReader(new InputStreamReader(System.in));
}catch (IOException e) {
System.out.println("Problem with trying to read/write to server: " + e);
}
}
#Override
public void run() {
String fromServer;
String fromClient;
while(true){
try{
if((fromServer = in.readLine()) != null) System.out.println(" " + fromServer);
else if((fromClient = stdIn.readLine()) != null) out.println(fromClient);
}catch(Exception e) {
System.out.println("msg exception: " + e);
}
}
}
}
}
Server side:
public class Server {
//Run server until keepGoing = false
private boolean keepGoing = true;
public static void main(String[] args) {
Server server = new Server();
server.go();
}
public void go() {
try {
ServerSocket serverSocket = new ServerSocket(5000);
while(keepGoing) {
Socket clientSocket = serverSocket.accept();
ClientThread t = new ClientThread(clientSocket);
t.start();
}
} catch (IOException e) {
System.out.println("Problem with socket/network: " + e);
}
}
class ClientThread extends Thread {
Socket clientSocket;
PrintWriter out;
BufferedReader in;
ClientThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try{
out = new PrintWriter(clientSocket.getOutputStream());
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
} catch (IOException e) {
System.out.println("Problem with creating in/out: " + e);
}
}
#Override
public void run() {
String message;
while(keepGoing) {
try{
message = in.readLine();
out.println(message);
System.out.println(message);
} catch (IOException e){
System.out.println("Exception while try to read line: " + e);
}
}
}
}
}
PS I've changed a bit the code - instead of made ClientThread Class, I made new runnable class and pass that variable to thread class. Inspired by this question: "implements Runnable" vs. "extends Thread".
I think the problem is that both server and client are waiting for any input. Server:
message = in.readLine();
Client:
if((fromServer = in.readLine()) != null)
System.out.println(" " + fromServer);
else if((fromClient = stdIn.readLine()) != null)
out.println(fromClient);
But the client code already blocks on the fromServer = in.readLine() part, so it never gets to read from standard in, and thus nothing will be sent out to the server.
You could move your attempt to read from standard in to the setUpNetworking method, right after the System.out.println("Type your message: ");. Build a loop there which you exit if the user types "exit" or "quit" or something like that:
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String read = "";
do {
read = stdIn.readLine();
System.out.println("Read from stdin: " + read);
serverThread.send(read);
}
while (!read.equals("exit"));
The ServerThread.send() method is simple:
void send(String string) {
System.out.println("Sending to server: " + string);
out.println(string);
}
However, to make it work, you either have to flush the stream manually after writing to out, or use the following constructor:
out = new PrintWriter(socket.getOutputStream(), true);
See the PrintWriter's JavaDoc: True means auto-flush on newline.
I tested this setup and it worked for me. I was able to send something from the client to the server.
However, this is only the first step. I would implement both reading and writing as separate threads, for both client and server. And there is no graceful shutdown of sockets implemenented yet. A more complete yet simple example can be found on Oracle.

the ReadLine doesnt wait for input

I have a socket client sending text to a socket server but the ReadLine doesnt seem to wait to receive a line before proceeding. Here is the of the server receiving the text:
public void run() {
try {
serveurSocket = new ServerSocket(PORT_ID);
connexionSocket = serveurSocket.accept();
BufferedReader reader = new BufferedReader(new InputStreamReader(connexionSocket.getInputStream()));
PrintWriter writer = new PrintWriter(connexionSocket.getOutputStream(), true);
messageRecu = "";
while (true) {
messageRecu = reader.readLine();
messageRecu = messageRecu.toUpperCase();
writer.println(messageRecu);
}
//reader.close();
//writer.close();
} catch (IOException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
After establishing the socket between client and server, the execution halts at reader.readLine until I send manually a string thru the socket. Which is normal and wanted. Codes resumes and its fine until its loops back to reader.ReadLine() where it will read a "null" line instead of waiting for input from the socket like it did the first time... this will obviously mess up the next command to uppercase. So how can I fix this?
EDIT: I'll add the client side if that can help understand.
public class ClientSocket {
private Socket clientSocket;
public boolean isClosed() { return clientSocket.isClosed(); }
public boolean connectToSocket (String ip, int port) {
try {
clientSocket = new Socket(ip, port);
return true;
}
catch (IOException e) {
System.out.println(e);
return false;
}
}
public String sendToServer(String messageClient) {
String messageRecu = "";
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter writer = new PrintWriter(clientSocket.getOutputStream(), true);
writer.println(messageClient);
messageRecu = reader.readLine();
reader.close();
writer.close();
return messageRecu;
}
catch (IOException e) {
System.out.println(e.getMessage());
e.printStackTrace();
return messageRecu;
}
}
}
A button press will call "connectTosocket" to initiate the socket. A second button when pressed will send the content of a textfield using "sendToServer".
Server does receive the message and return it capitalized but I wish for the socket to remain open with the server and if I send an other string for the same sequence to happen. Not even sure it can be done :(
According to the documentation of BufferedReader#readLine, a null is returned if the end of stream has been reached.
Change your reading loop to :
while ((messageRecu = reader.readLine()) != null) {
messageRecu = messageRecu.toUpperCase();
writer.println(messageRecu);
}
//Get out of the loop when the end of stream is reached.
As per Reading from and Writing to a Socket chapter of the Java tutorial.
As a side note, while(true) loops are not really appreciated.
The "null" signals for end of connection from the client side - which is why the connection disconnects. If you want to support multiple requests, you should run a new ServerSocket.accept() each time and wait for a new client to connect.
KKMultiServer class:
import java.net.*;
import java.io.*;
public class KKMultiServer {
public static void main(String[] args) throws IOException {
if (args.length != 1) {
System.err.println("Usage: java KKMultiServer <port number>");
System.exit(1);
}
int portNumber = Integer.parseInt(args[0]);
boolean listening = true;
try (ServerSocket serverSocket = new ServerSocket(portNumber)) {
while (listening) {
new KKMultiServerThread(serverSocket.accept()).start();
}
} catch (IOException e) {
System.err.println("Could not listen on port " + portNumber);
System.exit(-1);
}
}
}
KKMultiServerThread class:
import java.net.*;
import java.io.*;
public class KKMultiServerThread extends Thread {
private Socket socket = null;
public KKMultiServerThread(Socket socket) {
super("KKMultiServerThread");
this.socket = socket;
}
public void run() {
try (
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
) {
String inputLine, outputLine;
KnockKnockProtocol kkp = new KnockKnockProtocol();
outputLine = kkp.processInput(null);
out.println(outputLine);
while ((inputLine = in.readLine()) != null) {
outputLine = kkp.processInput(inputLine);
out.println(outputLine);
if (outputLine.equals("Bye"))
break;
}
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
You can read more about sockets in Oracle tutorials

Send message to server java

I'm creating chat program. At first, I send message to server from client and server should get message, but the message is not sent to the server until I shut down client.
Here is my code:
Client:
private Socket Client;
private Thread RunClient;
private JButton Send;
private int Port=8000;
private String Host="localhost";
public void init() {//Here we connecting to server
Send=new JButton();
Send.setFont(new Font("Times New Roman", Font.BOLD, 15));
Send.setLocation(575,Text.getHeight()+15);//395
Send.SetBorderColor(Color.cyan);
Send.setForeground(Color.white);
Send.setText("Send");
Send.setSize(30,70);
Send.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
SendButton_Click(e);
}
});
try
{
InetAddress address = InetAddress.getByName(Host);
Client = new Socket(address, Port);
System.out.println("Client started. Port: "+Port+"\n");
}catch(Exception e){
System.out.println("Error:"+e);
}
}
public void SendButton_Click(ActionEvent e) {//Here we sending message to server
String sendMessage = "hi";
try {
sendMessageToServer(Client,sendMessage);//sending message to server
} catch (IOException e1) {
e1.printStackTrace();
}
System.out.println("Message sent to the server : "+sendMessage);
}
}
private void sendMessageToServer(Socket socket,String message) throws IOException {
BufferedWriter writer = new BufferedWriter(new
OutputStreamWriter(socket.getOutputStream()));
writer.write(message);
writer.flush();
}
Here is server:
private int Port=8000;
public void init() {//Here we starting server and starting thread
try {
serverSocket = new ServerSocket(Port);
System.out.println("Server on. Port: "+Port+"\n");
} catch (IOException e1) {
e1.printStackTrace();
}
RunServer = new Thread() {
public void run() {
ServerLoop();
}
};
RunServer.start();
}
public void ServerLoop() {//here we should receive message..
while(true) {
System.out.println("Server loop");
try
{
Socket clientSocket = serverSocket.accept();
InputStreamReader inputstreamreader = new
InputStreamReader(clientSocket.getInputStream());
BufferedReader bufferedreader = new
BufferedReader(inputstreamreader);
PrintWriter printwriter = new
PrintWriter(clientSocket.getOutputStream(),true);
String line = "";
boolean done = false;
while (((line = bufferedreader.readLine()) != null) &&(!done)){
System.out.println("Received from Client: " + line);
if (line.compareToIgnoreCase("Exit") == 0) done = true;
}
}
catch (Exception e){
e.printStackTrace();
}
}
}
Your server is waiting for a full line, i.e. a String that is terminated with \r, \n, or both. Your client does not send a line ending, thus the server's call to readLine() cannot complete until the stream ends, when the remaining (non-line-terminated) input is returned.
Try sending "hi\n" and it should work.
The readLine() method will wait until it receives a newline character (\n) before returning. This means that the method blocks until the client is disconnected. The solution is simple; change the line in sendMessageToServer() that is
writer.write(message);
to
writer.write(message + "\n");
However, you will not be able to send the server messages containing \n without bugs. To do so, you will have to rewrite your reading code to use character-by-character reading.

Difficulty with socket communication from Server to Client

I have a relatively simple program where I try establish Client Server connection and at the same time I use threads in the client side to allow for multiple connections.
I run the server and then the server invokes the client constructor and passes the port connection to the client and the thread is started on the client side.
The problem I have is that when I run the server side it doesn't want to go beyond the constructor call. It seems to get stuck at the constructor.
Sorry all this sounds a bit confusing
Any thoughts perhaps
this is the server side
ServerMultipleThreads()
{
System.out.println("Starting the server first...");
try
{
ServerSoc = new ServerSocket(7777);
listening = true;
}
catch(Exception e)
{
System.out.println(e.toString());
System.exit(1);
}
System.out.println("The server has started running");
while(listening)
{
try
{
//creating the client socket and starting the new client session
new ClientSession(ServerSoc.accept());
System.out.println("The clientSession was called");
in = new DataInputStream(clientSocket.getInputStream());
BufferedReader is = new BufferedReader(new InputStreamReader(in));
os = new PrintStream(clientSocket.getOutputStream());
while(true)
{
line = is.readLine();
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("myFile,txt")), true);
out.println(line);
}
}
catch(IOException ioe)
{
System.out.println(ioe.toString());
}
}
}
and this is on client side
ClientSession(Socket s)
{
clientSocket = s;
try
{
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out.println("Welcome");
}
catch(IOException exe)
{
System.out.println(exe.toString());
}
//starting the thread
while(runner == null)
{
runner = new Thread(this);
runner.start();
}
}
public void run()
{
while(runner == Thread.currentThread())
{
BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
String stdIn;
try
{
while((stdIn = buf.readLine()) != null)
{
out.println(stdIn);
}
}
catch(IOException exe)
{
exe.toString();
}
try
{
Thread.sleep(10);
}
catch(InterruptedException e){}
}
Kind regards
Arian
That is because ServerSocket.accept() blocks until it receives a client request.
You need to have a client calling the server, something like this:
Socket socket = new Socket(host, port);
InputStream in = socket.getInputStream();
// write some data...

Categories

Resources