Socket connection using BufferedReader / BufferedWriter - java

My server is not sending a response with BufferedWriter out to the client. It seems as if the code stops at int amountOfNumbersToBeGenerated = Integer.parseInt(bufferedReader.readLine()); I believe the bufferedreader.readline() call on the client side is causing and issue and blocking the connection in some sense.
import java.io.*;
import java.net.Socket;
import java.util.ArrayList;
public class ThreadedConnection implements Runnable {
private Socket connection;
private InputStream in;
private OutputStream out;
public ThreadedConnection(Socket connection) {
this.connection = connection;
try {
this.in = this.connection.getInputStream();
this.out = this.connection.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void run() {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in));
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(out));
try {
String lotteryType = bufferedReader.readLine(); //reads first line of input stream
int amountOfNumbersToBeGenerated = Integer.parseInt(bufferedReader.readLine());
System.out.println("3"+amountOfNumbersToBeGenerated);
switch (lotteryType) {
case "LuckyForLife":
generateLotteryNumbers(amountOfNumbersToBeGenerated, 48, 18, bufferedWriter);
break;
case "MegaMillions":
generateLotteryNumbers(amountOfNumbersToBeGenerated, 70, 25, bufferedWriter);
break;
case "PowerBall":
generateLotteryNumbers(amountOfNumbersToBeGenerated, 69, 26, bufferedWriter);
break;
default:
break;
}
bufferedWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
connection.close();
bufferedReader.close();
bufferedWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void generateLotteryNumbers(int amountOfNumbersToBeGenerated, int upperLimitOfGeneratedNumbers, int upperLimitOfExtraNumber, BufferedWriter bufferedWriter){
RandomNumberGenerator randomNumbers = new RandomNumberGenerator(amountOfNumbersToBeGenerated,upperLimitOfGeneratedNumbers);
RandomNumberGenerator extraNumber = new RandomNumberGenerator(1,upperLimitOfExtraNumber);
ArrayList randomNumbersArrayList = randomNumbers.NumberGenerator();
ArrayList extraNumberArrayList = extraNumber.NumberGenerator();
String randomNumbersString = randomNumbersArrayList.toString();
randomNumbersString = randomNumbersString.substring(1, randomNumbersString.length()-1);
String extraNumberString = extraNumberArrayList.toString();
extraNumberString = extraNumberString.substring(1, extraNumberString.length()-1);
try {
bufferedWriter.write(randomNumbersString);
bufferedWriter.newLine();
bufferedWriter.write(extraNumberString);
bufferedWriter.newLine();
bufferedWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}
// System.out.println(randomNumbersString);
// System.out.println(extraNumberString);
}
}
Here is the code for the client side. I think the first String gerneretedNumber = bufferedReader.readLine(); is causing the issue. Almost as if it is called to read when there is nothing being written out from the server and then messing with the server side read. If I block both of the readline() calls the code on the server then works and I can get something to print out on console.
static void runClient(){
OutputStream outputStream;
InputStream inputStream;
Socket client;
BufferedWriter bufferedWriter;
BufferedReader bufferedReader;
try {
System.out.println("Creating client socket ");
client = new Socket("127.0.0.1", 5000);
outputStream = client.getOutputStream();
inputStream = client.getInputStream();
bufferedWriter = new BufferedWriter(new
OutputStreamWriter(outputStream));
//bufferedReader = new BufferedReader(new
InputStreamReader(System.in));
bufferedReader = new BufferedReader(new
InputStreamReader(inputStream));
bufferedWriter.write("LuckyForLife");
bufferedWriter.newLine();
bufferedWriter.write("5");
bufferedWriter.flush();
String generetedNumber = bufferedReader.readLine();
String extraNumber = bufferedReader.readLine();
System.out.println(gerneretedNumber);
System.out.println(extraNumber);
System.out.println("Guess its null");
bufferedReader.close();
bufferedWriter.close();
client.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
If anymore information is needed I am happy to post it.

your client never sends the 2nd newline.
Given your protocol, client doesn't half close (output close) so the server cannot either detect end of stream.
BTW, try to close streams (tcp FIN) before close socket (tcp RST); it's more "ethical" ! Kidding aside, the tcp rst is a kill, and pending bytes might not be flushed out (although you have plenty of flushes here, it's just good practice).

Related

InputStreamReader readLine method returns wrong String

I'm trying to send a string from my java server to an android client over a socket. Instead of showing the correct String which would be "OK" the read method of the InputStreamReader returns
"��OK".
The code of the server looks like this:
public void run() {
try {
DataOutputStream dOut = new DataOutputStream(socket.getOutputStream());
dOut.writeUTF("OK");
dOut.flush();
dOut.close();
socket.close();
System.out.println("Disconnected from client number: " + id);
} catch (IOException ex) {
Logger.getLogger(ThreadImpl.class.getName()).log(Level.SEVERE, null, ex);
}
}
And the code of the client looks like this:
public void run() {
try {
Socket socket = null;
try {
socket = new Socket("10.0.2.2", 1978);
} catch (IOException e) {
e.printStackTrace();
}
String serverRes = null;
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
ServerRes = reader.readLine();
System.out.println(ServerRes);
reader.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
You should be using a DataInputStream instead of an InputStreamReader. This is the source of your problem
InputStreamReader reader = new DataInputStream(socket.getInputStream()));
String inStr = reader.readUTF();

Sockets - No continuous response

I'm delving into sockets for the first time.
The point of the project is for the client to be able to get access to a contact list (CSV) in the server by writing "getall" and exit the program through just that command ("Exit").
The problem is that the client can only write the command and receive the list once and then the server doesn't respond to the client's input anymore.
Here is the socket code for the server and client respectively:
Server:
public class CatalogueServer extends CatalogueLoader {
ServerSocket serverSocket;
ArrayList<CatalogueEntry> catalogue;
public void startServer(int port, String catalogueFile) {
catalogue = loadLocalCatalogue(catalogueFile);
try {
serverSocket = new ServerSocket(port);
while (true) {
Socket clientSocket = serverSocket.accept();
new Thread(
new Runnable() {
public void run() {
try {
InputStream inputStream = clientSocket.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
BufferedReader BR = new BufferedReader(inputStreamReader);
OutputStream outputStream = clientSocket.getOutputStream();
PrintWriter PW = new PrintWriter(outputStream);
String clientInput;
while ((clientInput = BR.readLine()) != null) {
System.out.println(clientInput);
if (clientInput.equals("getall")) {
System.out.println(printCatalogue(catalogue));
PW.println(printCatalogue(catalogue));
PW.flush();
break;
} else if (clientInput.equals("exit")) {
clientSocket.close();
BR.close();
PW.close();
break;
} else {
PW.flush();
break;
}
}
PW.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
).start();
}
} catch (Exception i) {
i.printStackTrace();
}
}
}
Client:
public class TestClient {
public static void main(String[] args) {
try {
Socket socket = new Socket("localhost", 5253);
OutputStream outputStream = socket.getOutputStream();
InputStream inputStream = socket.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader BR = new BufferedReader(inputStreamReader);
while (true) {
String clientInput;
String serverFeedback;
PrintWriter PW = new PrintWriter(outputStream);
Scanner inputScan = new Scanner(System.in, "UTF-8");
clientInput = inputScan.nextLine();
PW.println(clientInput);
PW.flush();
while ((serverFeedback = BR.readLine()) != null) {
System.out.println(serverFeedback);
}
if (clientInput.equals("exit")) {
PW.close();
socket.close();
break;
}
PW.close();
}
}
catch (IOException e){
e.printStackTrace();
}
}
}
I have tried alternating the position and renewal of the readers and writers. But I'm uncertain of where exactly the problem starts.
When you do
while ((serverFeedback = BR.readLine()) != null) {
System.out.println(serverFeedback);
}
You are reading until you reach the end of the stream, i.e. until there is nothing left. As such there is nothing after this.
If you want to reuse the connection, you have to write the code which doesn't use this pattern and only reads until it should stop reading.

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!

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

BufferedReader readLine and OutputStreamWriter .write

I have 2 programs: a client and a server.
The server creates a ServerSocket and the client connects using:
address = InetAddress.getByName(host);
conn = new Socket(address, port);
this works, but here is the problem: void mousePressed() { gets called once the mouse is clicked, executing this: (client side)
void mousePressed() {
try {
BufferedOutputStream os = new BufferedOutputStream(conn.getOutputStream());
OutputStreamWriter osw = new OutputStreamWriter(os, "US-ASCII");
osw.write("123");
osw.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
the server should receive the input using:
BufferedReader reader = new BufferedReader(
new InputStreamReader(new BufferedInputStream(conn.getInputStream())));
StringBuilder result = new StringBuilder();
for (String line = null; (line = reader.readLine()) != null;) {
result.append(line);
}
reader.close();
println(result.toString());
The server only receives the input after the socket has been closed with: conn.close(); on the client side or quitting the client. As i want to be able to click the mouse multiple times, i can't close the socket.
What can i do to send input without closing the socket?
Edit: connection code:
Server:
// init
ServerSocket socket1;
int main_port = 5204;
// in main
try {
socket1 = new ServerSocket(main_port);
Socket conn = socket1.accept();
} catch (Exception e) {
e.printStackTrace();
}
Client:
// init
String host = "localhost";
int port = 5204;
Socket conn;
InetAddress address;
// in main
try {
address = InetAddress.getByName(host);
conn = new Socket(address, port);
} catch (Exception e) {
e.printStackTrace();
}
My solution (based on other answers and comments):
1) Changing osw.write("123"); to osw.write("123\n"); in the client.
2) Replacing
BufferedReader reader = new BufferedReader(new InputStreamReader(new
BufferedInputStream(thread_cnn.getInputStream())));
StringBuilder result = new StringBuilder();
for (String line = null; (line = reader.readLine()) != null;) {
result.append(line);
}
println(result);
reader.close();
with
BufferedReader reader = new BufferedReader(new InputStreamReader(new BufferedInputStream(conn.getInputStream())));
String result = reader.readLine().toString();
println(result);
reader = null;
result = null;
on the server.
You are writing an incomplete line, and trying to read complete lines. Terminate the text you send with a line break so it can be read when it arrives.
Also, do not catch and ignore exceptions. If something goes wrong you will want to know about it.
try {
BufferedOutputStream os = new BufferedOutputStream(conn.getOutputStream());
OutputStreamWriter osw = new OutputStreamWriter(os, "US-ASCII");
osw.write("123\n");
osw.flush();
} catch (Exception e) {
e.printStackTrace();
}

Categories

Resources