How to avoid blocking while using reader.readLine() and sc.nextLine() - java

I am using reader.readLine() and sc.nextLine() to simulate the server and client. However, after I typed some words in the scanner, the server responded nothing. I think the problem is thread blocking, but I can't correct it. Could any one help point out where the sticking point is.
Here is the code for server.
public class Server {
public static LocalDateTime currentTime() {
return LocalDateTime.now();
}
public static void main(String[] args) throws IOException, InterruptedException {
ServerSocket ss = new ServerSocket(9091);
System.out.println("TCP server ready.\n");
Socket sock = ss.accept();
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(sock.getInputStream(), StandardCharsets.UTF_8))) {
try (BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(sock.getOutputStream(), StandardCharsets.UTF_8))) {
String cmd;
System.out.println("read in");
while ((cmd = reader.readLine()) != null) {
System.out.println("Rcvd: " + cmd);
if ("time".equals(cmd)) {
writer.write(currentTime() + "\n");
writer.flush();
} else {
writer.write("Sorry?\n");
writer.flush();
}
}
}
}
sock.close();
ss.close();
}
}
The code for client
public class Client {
public static void main(String[] args) throws IOException, InterruptedException {
InetAddress addr = InetAddress.getLoopbackAddress();
try (Socket sock = new Socket(addr, 9091)){
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(sock.getInputStream(), StandardCharsets.UTF_8))){
try (BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(sock.getOutputStream(), StandardCharsets.UTF_8))){
Scanner sc = new Scanner(System.in);
String cmd;
while (sc.hasNext()) {
cmd = sc.nextLine();
System.out.println("Scanned: " + cmd);
writer.write(cmd);
writer.flush();
String resp = reader.readLine();
System.out.println("Response: " + resp);
}
}
}
}

Use this in Client:
writer.write(cmd + "\n");
since the server read lines.

Related

Java socket sends only one message

I have made a socket in Java.
This socket connects with a server.
When I start my program, the server sends a message that my socket is connected with the AEOS.
When I try to login to the server for sending some commands, then the server responds again with: status connected to AEOS version
This is not the message that I expect, normally my server must send a "response true".
Can you help me?
Thanks.
import java.io.*;
import java.net.*;
class TCPClient {
public static void main(String argv[]) throws Exception {
while(true) {
String sentence;
String modifiedSentence;
Socket clientSocket = new Socket("127.0.0.1", 1201);
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
sentence = inFromUser.readLine();
outToServer.writeBytes(sentence + '\n');
modifiedSentence = inFromServer.readLine();
System.out.println("FROM SERVER: " + modifiedSentence);
clientSocket.close();
}
}
}
output socket
Why don't you try to read everything that server had sent? Also, need to open a new Socket every-time? Depends on your implementation. Try this:
public static void main(String[] args) {
Socket clientSocket = null;
try {
clientSocket = new Socket("127.0.0.1", 1201);
BufferedReader inFromUser = new BufferedReader(
new InputStreamReader(System.in));
DataOutputStream outToServer = new DataOutputStream(
clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
String initialMessageFromServer = null;
while ((initialMessageFromServer = inFromServer
.readLine()) != null) {
System.out.println(initialMessageFromServer);
}
while (true) {
String sentence = inFromUser.readLine();
outToServer.writeBytes(sentence + '\n');
StringBuilder modifiedSentence = new StringBuilder();
String responseFromServer = null;
while ((responseFromServer = inFromServer.readLine()) != null) {
modifiedSentence.append(responseFromServer);
modifiedSentence.append('\n');
}
System.out
.println("FROM SERVER: " + modifiedSentence.toString());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (clientSocket != null) {
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

How to send ACK/NACK to server

Below is client and server program that I wrote. Now I am confused how to send ack/nack in my program.
I saw few answers on stackoverflow but i am still confused. Can you give an example of ACK/NACK in TCP protocol using java
Client:
public class Client {
public static void main(String args[]) {
try {
Socket client = new Socket("localhost", 2222);
PrintWriter pw = new PrintWriter(client.getOutputStream(), true);
Scanner input = new Scanner(System.in);
boolean a = true;
while (a) {
//receving
BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
System.out.println(br.readLine());
if (input.equals("q")) {
a = false;
client.close();
}
pw.println("Client0: " + input.nextLine());
System.out.println(pw);
// System.out.println("Request sent successfully");
}
} catch (Exception ex) {
System.out.println(ex);
}
}
}
Server:
public class Server {
public static void main(String args[]) {
try {
ServerSocket ss = new ServerSocket(2222);
System.out.println("Waiting for client request");
Socket client = ss.accept();
System.out.println("Accepted connection request");
Scanner input = new Scanner(System.in);
while (true) {
// receving
InputStreamReader isr = new InputStreamReader(client.getInputStream());
BufferedReader br = new BufferedReader(isr);
String str = br.readLine();
// sending
PrintStream ps = new PrintStream(client.getOutputStream());
ps.println("Server1: " + input.nextLine());
System.out.println(ps);
}
} catch (Exception e) {
System.out.println(e);
}
}
}
Thank you

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.

Java Client/Server don't communicate through Socket/ServerSocket

I have a simple socket/serversocket example that I'm trying to get running, but both the client and the server hang when their BufferedReaders try to read. Here is the code for each:
SERVER
package picturePerfect;
--imports--
public class PictureServer implements Runnable{
static ServerSocket serverSocket;
public static void main(String[] args) throws IOException {
serverSocket = new ServerSocket(2342);
Thread firstSessionThread = new Thread(new PictureServer());
firstSessionThread.start();
}
#Override
public void run() {
Socket socket = null;
try {
socket = serverSocket.accept();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String clientRequest = bufferedReader.readLine();
System.out.println(clientRequest);
PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);
printWriter.println("Sent from server!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
CLIENT
package picturePerfect;
--imports--
public class PictureClient {
public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException {
Socket socket = new Socket("localhost", 2342);
PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);
printWriter.write("Sent from client!");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String response = bufferedReader.readLine();
System.out.println(response);
socket.close();
}
}
This is the barest I could simplify my code to. I have a sample program that I've been following, which seems nearly exactly the same. This is the sample server and client (that does work):
SAMPLE SERVER
--imports--
public class Server implements Runnable{
static ServerSocket ss;
public static void main(String[] args) throws IOException {
ss = new ServerSocket(3142);
Thread thread = new Thread(new Server());
thread.start();
}
#Override
public void run() {
while ( true ) {
Socket s = null;
try {
s = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String operands = br.readLine();
System.out.println(operands + " was received");
PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
pw.println(operands + " right back!");
} catch ( IOException e ) {
e.printStackTrace();
}
}
}
}
SAMPLE CLIENT
--imports--
public class Server implements Runnable{
static ServerSocket ss;
public static void main(String[] args) throws IOException {
ss = new ServerSocket(3142);
Thread thread = new Thread(new Server());
thread.start();
}
#Override
public void run() {
while ( true ) {
Socket s = null;
try {
s = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String operands = br.readLine();
System.out.println(operands + " was received");
PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
pw.println(operands + " right back!");
} catch ( IOException e ) {
e.printStackTrace();
}
}
}
}
I've tried putting the while loop into my server and moving my client and server to the default package, but neither helped. I also tried using read() instead of readLine(), and ending the printWriter's lines with \r\n, but was just as unsuccessful there.
Why does my code hang on readLine(), especially when the sample code doesn't?
What readline() does is wait until it sees a new line character until it returns, hence readLine().
In your client, you do not write a new line. You use:
printWriter.write("Sent from client!");
Instead, write a newline character into the stream using println,
printWriter.println("Sent from client!");
Server expects to read line, so you need to add line separators after your massage. To do this instead of
printWriter.write("Sent from client!");
in client use
printWriter.println("Sent from client!");
// ^^^^^^^
or
printWriter.write("Sent from client!"+System.lineSeparator());
printWriter.flush();
You will need to flush yourself because autoflush in PrintWriter works only for println, printf, or format, not for write method

Statement after while not executing in the client program

I am trying to read a file from server and able to do it successfully. However, at the client end the statement after the while loop does not execute at all. Kindly help me with this request. The line asking for client input does not show up at all. Please help
//Client Side Code
import java.io.*;
import java.net.*;
import java.util.StringTokenizer;
import java.lang.*;
public class oss_client1 {
public static void main(String args[]) throws Exception {
Socket sock = new Socket("127.0.0.1", 2222);
char n1;
int choice;
// reading the file name from keyboard. Uses input stream
BufferedReader keyRead = new BufferedReader(new InputStreamReader(
System.in));
BufferedReader dis = new BufferedReader(
new InputStreamReader(System.in));
// receiving the contents from server. Uses input stream
InputStream istream = sock.getInputStream();
InputStream istream1 = sock.getInputStream();
// sending the file name to server. Uses PrintWriter
OutputStream ostream = sock.getOutputStream();
BufferedReader dRead = new BufferedReader(
new InputStreamReader(istream));
BufferedReader socketRead = new BufferedReader(new InputStreamReader(
istream1));
PrintWriter pwrite = new PrintWriter(ostream, true);
PrintWriter pwrite1 = new PrintWriter(ostream, true);
do {
System.out.println("Enter the website name: ");
String u_input = keyRead.readLine();
pwrite.println(u_input);
String str;
while ((str = dRead.readLine()) != null) {
// reading line-by-line
System.out.println(str);
}
str = dRead.readLine();
System.out.println(str);
dRead.close();
System.out
.print("\nPlease enter the product code which you want to buy: ");
String pcode = dis.readLine();
pwrite1.println(pcode);
String pcode_res = socketRead.readLine();
System.out.print("\nBack from server " + pcode_res + "\n");
System.out.println("\nDo you want to continue(Y/N)");
String n = dis.readLine();
n1 = n.charAt(0);
} while (n1 == 'Y' || n1 == 'y');
pwrite.close();
socketRead.close();
keyRead.close();
}
}
//Server side code
import java.net.*;
import java.util.*;
import java.io.*;
public class oss_server1 {
static Socket clientSocket = null;
static ServerSocket serverSocket = null;
static clientThread t[] = new clientThread[10];
public static void main(String args[]) throws Exception {
int port_number = 2222; // The default port
if (args.length < 1) {
System.out.println("Now using port number=" + port_number);
} else {
port_number = Integer.valueOf(args[0]).intValue();
}
/* Try to open a server socket on port port_number (default 2222) */
try {
serverSocket = new ServerSocket(port_number);
} catch (IOException e) {
System.out.println(e);
}
while (true) {
try {
clientSocket = serverSocket.accept();
for (int i = 0; i <= 9; i++) {
if (t[i] == null) {
(t[i] = new clientThread(clientSocket, t)).start();
port_number++;
break;
} // end of if loop
} // end for looop
}// end of try loop
catch (IOException e) {
System.out.println(e);
}
} // end of while loop
}
}
class clientThread extends Thread {
DataInputStream is = null;
DataOutputStream dout = null;
Socket clientSocket = null;
clientThread t[];
public clientThread(Socket clientSocket, clientThread[] t) {
this.clientSocket = clientSocket;
this.t = t;
}
public void run() {
try {
System.out.println("Welcome to US ONLINE SHOPPING SYSTEM");
String website = "www.US_OSS.com";
// buffer stream for reading the choice from client
InputStream istream = clientSocket.getInputStream();
InputStream istream1 = clientSocket.getInputStream();
BufferedReader webRead = new BufferedReader(new InputStreamReader(istream));
BufferedReader pcodeRead = new BufferedReader(new InputStreamReader(istream));
// buffer stream reading the file contents
BufferedReader displayRead = new BufferedReader(new FileReader(
"display_client.txt"));
BufferedReader prodRead = new BufferedReader(new FileReader(
"product_list.txt"));
// keeping output stream ready to send the contents
OutputStream ostream = clientSocket.getOutputStream();
PrintWriter pwrite = new PrintWriter(ostream, true);
String str, str1, pcode;
String fname = webRead.readLine();
if (fname.compareTo(website) != 0) {
pwrite.println("Error 404: NOT FOUND");
} else {
while ((str = displayRead.readLine()) != null) // reading line-by-line from file
{
pwrite.println(str);
}
displayRead.close();
str = "END OF PRODUCT LIST";
pwrite.println(str);
pcode = pcodeRead.readLine();
System.out.print("\nReceived PCODE is: " + pcode);
pwrite.println(pcode);
}
// pwrite.close();
} // end of try block
catch (IOException e) {
System.out.println(e);
}
} // end of run class
}// end of Client thread class
BufferedReader when reading after EOF will issue IOException
Instead I suggest you use Scanner to read files
Your code would look like...(in ServerSide)
Scanner scnFile=new Scanner(new File("display_client.txt")); //give absolute path if necessary
while(scnFile.hasNext()){
System.out.println(scnFile.nextLine());
}
scnFile.close();

Categories

Resources