Client socket doesn't take any input from cmd - java

I create a program where server sends a list of files to client which the client can then request to check the contents. It sends the list of files properly but then the client doesn't take any input from console.
This is the server program
import java.util.*;
import java.io.*;
import java.net.*;
class TCPServer{
public static void main(String args[]) throws Exception{
ServerSocket server = new ServerSocket(4888);
while(true){
Socket client = server.accept();
System.out.println(client);
DataOutputStream out = new DataOutputStream(client.getOutputStream());
File path = new File("C://testjava");
String[] files = path.list();
String send = "";
for(String file:files){
send = send + file + "\n";
}
out.writeBytes(send);
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream ()));
String search_file = in.readLine();
String searching = "";
for(String file:files){
if (file.equals(search_file)){
searching = search_file;
}
}
if(searching.equals("")){
out.writeBytes("Requested file does not exist");
client.close();
}
Scanner file = new Scanner(new FileReader(searching));
while(file.hasNextLine()){
out.writeBytes(file.nextLine());
}
client.close();
}
}
}
This is the client program
import java.util.*;
import java.io.*;
import java.net.*;
class TCPClient{
public static void main(String args[]) throws Exception{
Socket client = new Socket("localhost",4888);
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String display = "";
while ((display = in.readLine()) != null) {
System.out.println(display);
}
System.out.println("\nChoose a file");
Scanner src = new Scanner(System.in);
String ask_file = src.nextLine();
DataOutputStream out = new DataOutputStream(client.getOutputStream());
out.writeBytes(ask_file);
display = "";
while ((display = in.readLine()) != null) {
System.out.println(display);
}
}
}
Can anyone explain why the client isn't accepting any input?
Thanx

In the client, in.readLine() blocks until the Socket is closed.
Since you clearly don't want to close the socket yet, you could have the server send a special message to match for in the loop. When matched, break out of the loop.
Also, readLine/nextLine like methods gobble up newlines, so you need to add some like #EJP said. I edited your coded below. I tested it and it seems to be working now.
TCPServer
import java.util.*;
import java.io.*;
import java.net.*;
class TCPServer{
public static void main(String args[]) throws Exception{
ServerSocket server = new ServerSocket(4888);
while(true){
Socket client = server.accept();
System.out.println(client);
DataOutputStream out = new DataOutputStream(client.getOutputStream());
File path = new File("C://Users/Brian/Desktop");
String[] files = path.list();
String send = "";
for(String file:files){
send = send + file + "\n";
}
send = send + "END\n"; // ADD SOMETHING LIKE THIS ------------------------------>
out.writeBytes(send);
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream ()));
String search_file = in.readLine();
String searching = "";
for(String file:files){
if (file.equals(search_file)){
searching = search_file;
}
}
if(searching.equals("")){
out.writeBytes("Requested file does not exist");
client.close();
}
Scanner file = new Scanner(new FileReader(searching));
while(file.hasNextLine()){
out.writeBytes(file.nextLine() + "\n"); // ADD A NEWLINE HERE ------------------>
}
client.close();
}
}
}
TCPClient
import java.util.*;
import java.io.*;
import java.net.*;
class TCPClient{
public static void main(String args[]) throws Exception{
Socket client = new Socket("localhost",4888);
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String display = "";
// ADD A TEST FOR "END" HERE --------------------------------------------->
while ((display = in.readLine()) != null && !display.equals("END")) {
System.out.println(display);
}
System.out.println("\nChoose a file");
Scanner src = new Scanner(System.in);
String ask_file = src.nextLine() + "\n"; // ADD A NEWLINE HERE ----------->
DataOutputStream out = new DataOutputStream(client.getOutputStream());
out.writeBytes(ask_file);
display = "";
while ((display = in.readLine()) != null) {
System.out.println(display);
}
}
}

You're reading lines but you aren't writing lines. You need to add a \n to the strings you're writing with writeBytes(). Otherwise readLine() blocks forever waiting for a line terminator that never arrives.

Related

How do I automatically say the knock knock jokes, with a delay of one second?

In the Java networking tutorial, we find the KnockKnock Client/Server pair. So I want to sit back and have the KnockKnockClient automatically send the clues to the server classes (which are KnockKnockServer/KnockKnockProtocol ). Here is what I tried :
import java.net.*;
import java.io.*;
import javax.swing.Timer;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class KnockKnockClientRedone {
static String KKJokes[] = { "Who's there?", "Turnip who?", "y", "Who's there?", "Little Old Lady who?", "y", "Who's there?", "Doctor who?", "y" };
public static void main(String[] args) throws IOException {
Socket kkSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try {
kkSocket = new Socket("localhost", 4444);
out = new PrintWriter(kkSocket.getOutputStream(), true);
for (int i = 0; i< KKJokes.length; i++) {
try {
Thread.sleep(1500); }
catch(Exception e){
e.printStackTrace();
}
in = new BufferedReader(
new InputStreamReader(
new ByteArrayInputStream(
KKJokes[i].getBytes()) ) );
}
} //try
catch ( IOException io ){
System.err.println("Calling IO . toString " + io.toString()); //System
System.exit(1);
}//catch
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String fromServer;
String fromServer2;
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();
}
}
But I noticed that something is wrong with my code here :
in = new BufferedReader(
new InputStreamReader(
new ByteArrayInputStream(
KKJokes[i].getBytes()) ) );
It only loops through til the end, and then in contains the last String in the String array. What I need is for the Client to send a String over the client, then proceed to the next String only when the Server sends back. Since I'm on a local machine, I thought that a delay of 1 second would be sufficient.
Any tips appreciated thanks

Can't run TCP client/server code on using cmd

I have this code but it doesn't run on cmd using windows. Doing this for the first time. When I try to run the server, there is no response (no error, but can't continue typing and nothing happens, and the same for the client1.
This is the code for the server:
import java.io.*;
import java.net.*;
public class outputStream
{
public static void main (String args [])throws Exception {
// initialises Server Socket
ServerSocket welcomeSocket = new ServerSocket (1337);
// waits for the connection of two clients C1 and C2 (in either order)
while (true) {
Socket socket1 = welcomeSocket.accept();
Socket socket2 = welcomeSocket.accept();
//gets input streams of the clients
BufferedReader inFromclient1 = new BufferedReader (new InputStreamReader(socket1.getInputStream()));
BufferedReader inFromclient2 = new BufferedReader (new InputStreamReader(socket2.getInputStream()));
//reads the data
String client1Sentence = inFromclient1.readLine();
String client2Sentence = inFromclient2.readLine();
//get output streams of the clients
BufferedWriter outToclient1 = new BufferedWriter (new OutputStreamWriter (socket1.getOutputStream ()));
BufferedWriter outToclient2 = new BufferedWriter (new OutputStreamWriter (socket2.getOutputStream ()));
//replies to clients
String reply1 = " ";
String reply2 = " ";
if (client1Sentence.equals(client2Sentence)){
reply1 = "xxxxx\n";
reply2 = "yyyyy\n";
} else if (client1Sentence.equals ('y') && client2Sentence.equals ('z')) {
reply1 = "xxx\n";
reply2 = "yyyyyy";
}
else if (client1Sentence.equals ('z') && client2Sentence.equals ('y')) {
reply1 = "xxxx\n";
reply2 = "yyyy\n";
}
else if (client1Sentence.equals ('y') && client2Sentence.equals ('x')) {
reply1 = "xxxxxxxx\n";
reply2 = "yyyyy\n";
}
else if (client1Sentence.equals ('P') && client2Sentence.equals ('R')) {
reply1 = "xxxxxxx\n";
reply2 = "yyyy\n";
}
else if (client1Sentence.equals ('z') && client2Sentence.equals ('x')) {
reply1 = "xxxx\n";
reply2 = "yyyyyyy\n";
}
else if (client1Sentence.equals ('x') && client2Sentence.equals ('z')) {
reply1 = "xxxxx\n";
reply2 = "yyyyyyy\n";
}
//sends reply to clients
outToclient1.write(reply1,0,reply1.length());
outToclient2.write(reply2,0, reply2.length());
//ends connection
outToclient1.flush();
outToclient2.flush();
}
}
}
This is the code for Client1:
import java.io.*;
import java.net.*;
public class client1
{
/**
* Constructor for objects of class clientTCP
*/
public static void main (String args[]) throws Exception {
//intialises input/outputStream
BufferedReader inFromUser = new
BufferedReader (new InputStreamReader (System.in));
//intialises client Socket
Socket clientSocket = new Socket ("localhost",1337);
//fetches input/outputSteam
BufferedReader inFromServer = new BufferedReader (new InputStreamReader(clientSocket.getInputStream()));
BufferedWriter outToServer = new BufferedWriter (new OutputStreamWriter(clientSocket.getOutputStream ()));
//sends message to server and closes server connection
String sentence = inFromUser.readLine();
outToServer.write (sentence + "\n", 0, sentence.length()+1);
outToServer.flush();
//server reads line from client
String ack = inFromServer.readLine();
//server replies to client
System.out.println ("FROM SERVER:" + ack);
// client socket is closed
clientSocket.close();
}
}
welcomeSocket.accept() will block until a client connects, so unless you run two clients and one server, nothing will happen
The problem goes with the use of the equals(), the arguments should be enclosed in a double quotation and not a single quotation.

While Loop not working as it should be

Client will request for a file, if the file exist in server then the server send the file and give a confirmation message. So i want to take input using the main while loop but it stops working after first iteration,
client side
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class WebClient {
public static void main(String[] args) throws Exception {
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
String req;
System.out.println("Do you want to search? (Y/N): ");
Scanner user_input = new Scanner(System.in);
req = user_input.next();
while (req.equals("Y")) {
Socket clientSocket = new Socket("localhost", 2000);
System.out.println("Enter the file name: ");
String file = inFromUser.readLine();
DataOutputStream serverOutput = new DataOutputStream(clientSocket.getOutputStream());
serverOutput.writeBytes(file + '\n');
BufferedReader serverInput = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
System.out.println("Text from the file: ");
while (true) {
String data = serverInput.readLine();
if (data == null) {
break;
}
System.out.println(data);
}
clientSocket.close();
System.out.println("Do you want to search again? (Y/N): ");
req = user_input.next();
}
}
}
server side
import java.io.*;
import java.net.*;
public class WebServer {
public static void main(String[] args) throws Exception
{
ServerSocket welcomeSocket = new ServerSocket(2000);
while (true)
{
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
String file = inFromClient.readLine();
System.out.println("Client Request: " + file); //Show The Client Request File
String path = ("E://From Varsity//4.2//Lab//Network Programming//Java trying//New TCP-Client+Server//tcp")+ "/" + file ;
File objfile = new File(path);
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
if (objfile.exists())
{
String readfile = rfile(path);
outToClient.writeBytes("\n" +readfile + "200 ok \n"); // when exact file find
}
else
{
outToClient.writeBytes("404 The Requested File not found \n"); // file not found
}
}
}
public static String rfile(String file_N) throws Exception
{
StringBuilder app = new StringBuilder();
BufferedReader bufferR = new BufferedReader(new FileReader(file_N));
try
{
String line = bufferR.readLine(); // read file from buffer
while (line != null) {
app.append(line); // append the line
app.append("\n");
line = bufferR.readLine();
}
}
finally
{
bufferR.close();
}
return app.toString();
}
}
Any help will be appreciated , thanks in advance
java.net.Socket is blocking. It'll block until it receives a close (the call to readLine() blocks until more data is available)
3 solutions:
Simplest: add outToClient.close() after the write.
Nonblocking: Use java.nio.SocketChannel/java.nio.ServerSocketChannel
Threaded: Create a new thread each time ServerSocket.accept() fires with the Socket object from accept.

How to return condition in a switch statement to while?

How to return action to while loop in a switch statement ? The client is unable to return to while statement. I meant to say, whenever response comes from server, the client must start from while loop again, so that client can select his choices. Is it a problem of System.out ? (Note: It's a copied code from others) Here are the client and server :
Client:
.............
while (true) {
String userchoice = console.readLine("Enter your choice :");
int choice= Integer.parseInt(userchoice);
switch (choice){
..........
case 2: // for viewing files in the client's directory
try{
Socket mysoc = new Socket("localhost", 9001);
String user_name = username;
DataOutputStream ToServer = new DataOutputStream(mysoc.getOutputStream());
ToServer.writeBytes(user_name + '\n');
BufferedReader FromServer = new BufferedReader(new InputStreamReader(mysoc.getInputStream()));
String line = null;
while ((line = FromServer.readLine()) != null) {
System.out.println(line);
}
}
catch(Exception e)
{
e.printStackTrace();
System.exit(0);
}
break;
............
}
Server:
import java.io.*;
import java.net.*;
class DirList
{
public static void main(String argv[]) throws Exception
{
String clientString;
//String replyString;
ServerSocket welcomeSoc = new ServerSocket(9001);
while(true)
{
Socket connectionSocket = welcomeSoc.accept();
BufferedReader FromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
PrintWriter ToClient = new PrintWriter(connectionSocket.getOutputStream(),true);
clientString = FromClient.readLine();
System.out.println("Received view songs request from : " + clientString);
String path = "/home/sri/Songs/";
String text="";
File f = new File(path);
File[] listOfFiles = f.listFiles();
for (int j = 0; j < listOfFiles.length; j++) {
if (listOfFiles[j].isFile()) {
text = listOfFiles[j].getName();
ToClient.println(text);
}
}
}
}
}
Why don't you label the outermost while like this..
outer: while(true)
and use the continue keyword to return to the label.
continue outer;
try to close your PrintWriter and Socket in the Server code after they finished their task.
#Sri, about the question you've asked in the comment:
by Socket I meant connectionSocket. ServerSocket will remain there during your server life time. But you will have a new connectionSocket for each user. so each connectionSocket will serve only a single client.

Sending file list from Server to Client in java Socket programming - PrintWriter can't send?

How can I send the file listing to client from server using Socket programming. I have used DataOutputStream and PrintWriter, both returns only one file name to Client. I know there is some problem in '\n'. But unable to solve it. Awaiting experts advice ... Thank you.
Client
switch (choice) {
.......
case 2: // for viewing files in the client's directory
Socket mysocket = new Socket("localhost", 6103);
String user_name = username;
DataOutputStream outToServer2= new DataOutputStream(mysocket.getOutputStream());
outToServer2.writeBytes(user_name + '\n');
BufferedReader inFromServer2 = new BufferedReader(newInputStreamReader(mysocket.getInputStream()));
String list = inFromServer2.readLine();
System.out.println("FROM SERVER - LIST OF FILES:" + list);
break;
}
.......
Server
import java.io.*;
import java.net.*;
class DirList
{
public static void main(String argv[]) throws Exception
{
String clientSentence;
String capitalizedSentence;
ServerSocket welcomeSocket = new ServerSocket(6103);
while(true)
{
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
PrintWriter outToClient = new PrintWriter(connectionSocket.getOutputStream(),true);
clientSentence = inFromClient.readLine();
System.out.println("Received view files request from user: " + clientSentence);
String path = "/home/user/Files/";
String userdir = path + clientSentence;
String text="";
String capitalizedSentence1;
File f = new File(userdir);
File[] listOfFiles = f.listFiles();
for (int j = 0; j < listOfFiles.length; j++) {
if (listOfFiles[j].isFile()) {
text = listOfFiles[j].getName();
outToClient.println(text);
System.out.print(text+' ');
}
}
}
}
}
You need to flush the output from your server:
outToClient.flush();
Also, in your client, you need to place the read in a loop to consume all the output:
String line = null;
while ((line = inFromServer2.readLine()) != null) {
System.out.println(line);
}
Try using "\r\n". It might solve your problem.

Categories