I have a simple client/server chat in java using Socket. The problem is the program connect to each other but I can't get/receive data from both side for some reasons. When I disconnect the server the client give me an error " Connection reset" which shows that they are connected but they don't exchange data.
The code are the same code taken from Java Tutorial taken from here.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package javaapplication3;
/**
*
* #author Amr
*/
import java.net.*;
import java.io.*;
public class KnockKnockServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(4440);
} catch (IOException e) {
System.err.println("Could not listen on port: 4444.");
System.exit(1);
}
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
System.out.println(Inet4Address.getLocalHost());
} catch (IOException e) {
System.err.println("Accept failed.");
System.exit(1);
}
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
clientSocket.getInputStream()));
String inputLine, outputLine;
while ((inputLine = in.readLine()) != null) {
outputLine = "heelo";
out.println(outputLine);
if (outputLine.equals("Bye."))
break;
}
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
}
import java.io.*;
import java.net.*;
public class KnockKnockClient {
public static void main(String[] args) throws IOException {
Socket kkSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try {
kkSocket = new Socket(Inet4Address.getLocalHost(), 4440);
out = new PrintWriter(kkSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host: taranis.");
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: taranis.");
System.exit(1);
}
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String fromServer;
String fromUser;
while ((fromServer = in.readLine()) != null) {
System.out.println("Server: " + fromServer);
if (fromServer.equals("Bye."))
break;
fromUser = stdIn.readLine();
if (fromUser != null) {
System.out.println("Client: " + fromUser);
out.println(fromUser);
}
}
out.close();
in.close();
stdIn.close();
kkSocket.close();
}
}
After setting up the connection, the first thing your server does is
while ((inputLine = in.readLine()) != null)
that is, it waits for the client to say something.
The first thing your client does is
while ((fromServer = in.readLine()) != null)
that is, it waits for the server to say something.
Make one of the two send something first and it should work.
The bit you're missing from that tutorial is this block:
// initiate conversation with client
KnockKnockProtocol kkp = new KnockKnockProtocol();
outputLine = kkp.processInput(null);
out.println(outputLine);
Currently, you are not initialising the conversation, hence the socket read blocking pointed out by other posters.
You have a single thread on both the client and the server that reads from their respective BufferedReader, using the readLine() method, which blocks.
Since both the client and server are expecting to read from one another before either of them sends anything, they'll both just sit there and block. You either need to fork and have a thread that reads from the BufferedReader and one that writes to the PrintWriter, or you have to have:
outputLine = "heelo";
out.println(outputLine);
outside of your while loop.
Related
In my client-server application, the client sends message to Server and the Server should display the message. But in my case, the client is only able to send but the server can't achieve it.
I have tried with different port numbers (i.e. 8080, 8000, 4444 etc). It seems that the socket can set up the connection, but I really don't know why the server can't read the input from client.
This is my complete project (I have ignored the main classes for both application here, because I have nothing more than just calling the methods):
EchoServer.java:
package client.server;
import java.io.*;
import java.net.*;
public class EchoServer {
public EchoServer() {
}
public void establish() {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(8080);
} catch (IOException e) {
System.out.println("Could not listen on port: 1234");
System.exit(-1);
}
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.out.println("Accept failed: 1234");
System.exit(-1);
}
PrintWriter out = null;
BufferedReader in = null;
try {
out = new PrintWriter(
clientSocket.getOutputStream(), true);
in = new BufferedReader(
new InputStreamReader(
clientSocket.getInputStream()));
} catch (IOException ioe) {
System.out.println("Failed in creating streams");
System.exit(-1);
}
String inputLine, outputLine;
try {
while ((inputLine = in.readLine()) != null) {
out.println(inputLine);
if (inputLine.equals("Bye.")) {
break;
}
}
} catch (IOException ioe) {
System.out.println("Failed in reading, writing");
System.exit(-1);
}
try {
clientSocket.close();
serverSocket.close();
} catch (IOException e) {
System.out.println("Could not close");
System.exit(-1);
}
}
}
EchoClient.java:
package server.client;
import java.io.*;
import java.net.*;
public class EchoClient {
public EchoClient() {
}
public void establish() {
Socket echoSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try {
//echoSocket = new Socket(InetAddress.getLocalHost(), 1234);
echoSocket = new Socket(InetAddress.getLocalHost(), 8080);
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(
echoSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host.");
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O");
System.exit(1);
}
BufferedReader stdIn = new BufferedReader(
new InputStreamReader(System.in));
String userInput;
try {
while ((userInput = stdIn.readLine()) != null) {
out.println(userInput);
if (userInput.equals("Bye.")) {
break;
}
System.out.println("echo: " + in.readLine());
}
out.close();
in.close();
stdIn.close();
echoSocket.close();
} catch (IOException ioe) {
System.out.println("Failed");
System.exit(
-1);
}
}
}
Your server doesn't write the incoming text to the console but only back to the client which doesn't handle incoming text from the server yet.
(out isn't System.out but Socket.out!)
In your server you are listening with readLine() in whileloop
while ((inputLine = in.readLine()) != null) {
System.out.println("inputLine "+inputLine);
which is nothing but the inputstream from client. The above SOP will print the message from client. Try to flush your streams because it won't print until your buffer is full.
Code seems to be fine. If you write some thing on PrintWriter at both server & client ends, you will get output.
Add below code in server: ( After creating Socket with accept() API)
out.println("Hello from Server");
Add below code in client ( After creating Socket)
out.println("Hello from client");
Other suggestions:
1) Create a thread once you accept a Socket Connection at server and that thread should handle all IO processing
2) You can create thread at client end too after creating Socket with Server. The new thread should handle all IO processing
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
Am writing a Server, client chat program using Java Socket. Here is my code for the Server socket class.
import java.io.*;
import java.net.*;
public class Main {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(8085);
} catch (IOException ex) {
System.out.println("IO Error, " + ex);
System.exit(1);
}
Socket clientSocket = null;
System.out.println("Listening for incoming connections");
try {
clientSocket = serverSocket.accept();
} catch (IOException ex) {
System.out.println("Failed to accept connection " + ex);
System.exit(1);
}
System.out.println("Connection Successful");
System.out.println("Listening to get input");
PrintStream output = new PrintStream(clientSocket.getOutputStream(), true);
BufferedReader input = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String inputLine;
while ((inputLine = input.readLine()) != null) {
System.out.println(inputLine);
System.out.println("Server: ");
inputLine = input.readLine();
output.println(inputLine);
if (!inputLine.equals("exit")) {
} else {
break;
}
}
output.close();
input.close();
clientSocket.close();
serverSocket.close();
}
}
The client is able to make a connection and send a message to the server. The server can also receive the messages sent by the client. The problem is that when the message is sent from the server, the client does not receive the message. Here is my client socket code.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
public class Client {
public static void main(String [] args) throws Exception
{
BufferedReader input;
PrintStream output;
BufferedReader clientInput;
try (Socket client = new Socket("127.0.0.1", 8085)) {
input = new BufferedReader(new InputStreamReader(client.getInputStream()));
output = new PrintStream(client.getOutputStream());
clientInput = new BufferedReader(new InputStreamReader(System.in));
String line;
while(true)
{
System.out.println("Client: ");
line = clientInput.readLine();
output.println("Server: " + line );
if(line.equals("quit"))
{
break;
}
}
}
input.close();
clientInput.close();
output.close();
}
}
Server side:
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(8085);
} catch (IOException ex) {
System.out.println("IO Error, " + ex);
System.exit(1);
}
Socket clientSocket = null;
System.out.println("Listening for incoming connections");
try {
clientSocket = serverSocket.accept();
} catch (IOException ex) {
System.out.println("Failed to accept connection " + ex);
System.exit(1);
}
System.out.println("Connection Successful");
System.out.println("Listening to get input");
PrintStream output = new PrintStream(clientSocket.getOutputStream(), true);
BufferedReader input = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String inputLine;
while ((inputLine = input.readLine()) != null) {
System.out.println("Client request: " + inputLine);
String resp = "some response as you need";
output.println(resp);
System.out.println("Server response: " + resp);
if (!inputLine.equals("exit")) {
} else {
break;
}
}
output.close();
input.close();
clientSocket.close();
serverSocket.close();
}
}
Client side:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
public class Client {
public static void main(String[] args) throws Exception {
BufferedReader input;
PrintStream output;
BufferedReader clientInput;
try (Socket client = new Socket("127.0.0.1", 8085)) {
input = new BufferedReader(new InputStreamReader(client.getInputStream()));
output = new PrintStream(client.getOutputStream());
clientInput = new BufferedReader(new InputStreamReader(System.in));
while (true) {
String inputStr = clientInput.readLine();
output.println(inputStr);
System.out.println("Client: " + inputStr);
if (inputStr.equals("quit")) {
break;
}
String serverResp = input.readLine();
output.println("Server: " + serverResp);
}
}
}
}
It is tested.
It's always a good idea to flush your output streams when you are done with them, the info you are sending may have buffered.
The server is expecting an extra line from the client input here:
while ((inputLine = input.readLine()) != null) {
System.out.println(inputLine);
System.out.println("Server: ");
inputLine = input.readLine(); // <--- here
The client is not reading from the InputStream called input it gets when it connects to the server. It is only reading the local console input from clientInput.
In the while loop in Client.java you need something like this after the quit block to get the server's response:
System.out.println("Server: " + input.readLine());
Apologies as I asked something similar last night, but I have narrowed my problem down. I am wondering how to make my Java TCP Socket Server read in the data sent using the printWriter(out) in the Client code from a GUI as it does from the command line stdin.
I have the following classes as an example and everything works fine until the GUI comes into the equation. The data is being sent over to the Server from the GUI as I can echo it on the server side, but it is not being read and parsed properly as the stdin is. Nothing is being sent back to the client. I have tried flushing, using different streams and adding line separators all over the place to no avail. There is also a Protocol class that handles the data on the Server side.
public class KnockKnockServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(4444);
System.out.println("Waiting for client...");
} catch (IOException e) {
System.err.println("Could not listen on port: 4444.");
System.exit(1);
}
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.err.println("Accept failed.");
System.exit(1);
}
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String inputLine, outputLine;
KnockKnockProtocol kkp = new KnockKnockProtocol();
outputLine = kkp.processInput(null);
out.println(outputLine);
while ((inputLine = in.readLine()) != null) {
System.out.println(inputLine);
outputLine = kkp.processInput(inputLine);
out.println(outputLine);
if (outputLine.equals("Bye.")) {
break;
}
}
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
}
.
public class KnockKnockClient {
public static PrintWriter out = null;
public static String sendAnswer;
public static void Client() {
//JButton Action Listener
saveAnswer.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ButtonModel b = group.getSelection();
if (b.getActionCommand() == "A") { sendAnswer = radioA.getText(); }
String data = "รท" + sendAnswer;
out.println(data);
}
});
}
public static void main(String[] args) throws IOException {
KnockKnockClient.Client();
Socket kkSocket = null;
//PrintWriter out = null;
BufferedReader in = null;
try {
kkSocket = new Socket("localhost", 4444);
out = new PrintWriter(kkSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host: localhost.");
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: localhost.");
System.exit(1);
}
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String fromServer, fromUser;
while ((fromServer = in.readLine()) != null) {
System.out.println("Server: " + fromServer);
if (fromServer.equals("Bye."))
break;
fromUser = stdIn.readLine();
if (fromUser != null) {
System.out.println("Client: " + fromUser);
out.println(fromUser);
}
}
out.close();
in.close();
stdIn.close();
kkSocket.close();
}
}
I use this code to run simple TCP Server by JAVA and I use Socket Protocol android application to be client. The problem is when the client connected then I send the message the Server side do nothing until I disconnected the client the massage appear after that. I think something stuck at
while((inputLine = in.readLine()) != null)
import java.net.*;
import java.io.*;
public class TCPIP {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
try{
serverSocket = new ServerSocket(10007);
}
catch(IOException e)
{
System.err.println("Could not listen on port 10007");
//System.exit(1);
}
Socket clientSocket = null;
System.out.println("Waiting for connection....");
try{
clientSocket = serverSocket.accept();
}
catch(IOException e){
System.err.println("Accept Failed");
//System.exit(1);
}
System.out.println("Connection Successful");
System.out.println("Waiting for input");
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(),true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String inputLine;
while((inputLine = in.readLine()) != null)
{
System.out.println("Server: "+ inputLine);
out.println(inputLine);
if(inputLine.equals("Bye."))
{
break;
}
}
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
}
while((inputLine = in.readLine()) != null)
is bad code, you should use
inputLine = in.readLine();
while(inputLine != null)
{
inputLine = in.readLine();
}
instead. readLine() waits for the newline-character - make sure your server sends it or else your client will block until the connection is closed : https://docs.oracle.com/javase/6/docs/api/java/io/BufferedReader.html#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.