I'm facing a problem with a need to double "enter" in order for the program to proceed, can someone enlighten me?
public void run() {
try {
out.write("Enter message to encrypt: \n");
out.flush();
while (true) {
entry = in.readLine();
result = caesarCipher(entry);
out.write("The encrypted message is " + result);
out.write("\tType q to end else type another message to encrypt");
out.flush();
}
} catch (IOException e) {
System.out.println(e);
}
}
this is over at the client side
public EncryptClient() throws IOException {
Socket cSock = new Socket("LocalHost", portNumber);
Reader iRead = new InputStreamReader(cSock.getInputStream());
input = new BufferedReader(iRead);
userTerminal = new BufferedReader(new InputStreamReader(System.in));
output = new OutputStreamWriter(cSock.getOutputStream());
while (true) {
String line = input.readLine();
System.out.println(line);
line = userTerminal.readLine();
if (line.equals("q")) {
break;
}
output.write(line + "\n");
output.flush();
}
}
when my client class is connect to the server class, i will need to enter a message for encryption, but a double enter is needed to show the result. can someone enlighten me?
ReadLine will halt the control of flow.
In your code, they were two readLine
.readLine(); // (line string is overrided twice)duplicated. Remove it. You will be fine.
Related
I'm open for other ways to do this, but this is my code:
public class Client {
public static void main (String [] args) {
try(Socket socket = new Socket("localhost", 7789)) {
BufferedReader incoming = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter outgoing = new PrintWriter(socket.getOutputStream(),true);
StringBuilder sb = new StringBuilder();
Scanner scanner = new Scanner(System.in);
String send = "";
String response = "";
while (!send.equals("logout")){
System.out.println("Enter Command: ");
send = scanner.nextLine();
outgoing.println(send);
while ((response = incoming.readLine()) != null) {
System.out.println(response);
sb.append(response);
sb.append('\n');
}
}
} catch (IOException e) {
System.out.println("Client Error: "+ e.getMessage());
}
}
}
I do get response from the server, but the program is getting stuck in the inner while loop while ((response = incoming.readLine()) != null), so i can't enter a second command. how do i break the loop if the incoming response is done ?
The problem is that incoming.readLine() will only return null if the socket is closed, otherwise it will block and wait for more input from the server.
If you can change the server, you could add some marking that the request was fully processed and then check it like this while ((response = incoming.readLine()) != "--finished--").
If you cannot, try this:
while(response.isEmpty()){
if(incoming.ready()){ //check if there is stuff to read
while ((response = incoming.readLine()) != null){
System.out.println(response);
sb.append(response);
sb.append('\n');
}
}
}
Client code snippet. Basically it reads from standard input and sends message to the server.
public static void main(String[] args) {
try (Socket socket = new Socket("localhost", 1200)) {
OutputStreamWriter writer = new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.US_ASCII);
Scanner scanner = new Scanner(System.in);
for (String msg = scanner.nextLine(); !msg.equals("end"); msg = scanner.nextLine()) {
writer.write(msg + "\n");
writer.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
Server code snippet. Prints a message from stream.
public void run() {
try (InputStreamReader reader = new InputStreamReader(this.socket.getInputStream(), StandardCharsets
.US_ASCII)) {
StringBuilder builder = new StringBuilder();
for (int c = reader.read(); c != -1; c = reader.read()) {
builder.append((char) c);
if ((char) c == '\n')
System.out.print(builder);
}
} catch (IOException e) {
e.printStackTrace();
}
}
Input from client:
Text1
Text2
Server output:
Text1
Text1
Text2
The problem I am facing that server prints not just received message but also all messages before it.
Question: How can I reset 'clean' InputStream without closing it. And if that is impossible what is preferred solution?
You don't need to 'clean' the stream--you just need to reset the buffer after every line. Try something like the following using StringBuilder.setLength:
if (c == '\n') {
System.out.print(builder.toString());
builder.setLength(0);
}
On the other hand, I'd strongly encourage not manually reading lines like that. Consider using a Scanner like you do in the client code or alternatively a BufferedReader.
try (final BufferedReader reader
= new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.US_ASCII))) {
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
System.out.println(line);
}
} catch (final IOException ex) {
ex.printStackTrace();
}
I'm Playing with a simple Client and Server application using socket, and i attempt to print a message in the console and get a response from the server but nothing shows up, i'm fairly new to sockets so i assume i have a logical error. It's a simple app that i want the client to prompt a user a user for a command (in my case an input string where the server will perform an action based on the 'thcharacter), send it to the server and just display the server response.I'm pretty sure my client isn't correct, can someone points out why i can't write anything from the client console.
package socketProgramming;
import java.io.*;
import java.net.*;
public class MyClient {
#SuppressWarnings("resource")
public static void main(String[] args) {
// TODO Auto-generated method stub
Socket socket= new Socket();
BufferedReader in = null;
String msg;
int port = 2222;
try {
System.out.println("CLient wants to connect on port: "+port);
socket = new Socket(InetAddress.getLocalHost().getHostAddress(), port);
System.out.println("The client is connected");
} catch (UnknownHostException e) {
System.exit(1);
} catch (IOException e) {
System.out.println("connect failed");
System.exit(1);
}
try{
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintStream output = new PrintStream(socket.getOutputStream());
String text = null;
output.print(text);
while ((text = input.readLine()) != null){
System.out.println("Client "+text);
}
socket.close();
System.out.println("Client Exiting");
}
catch(IOException e) {
System.out.println(e);
}}
}
package socketProgramming;
import java.io.*;
import java.net.*;
public class MyServer {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
String msg = "";
ServerSocket sSocket = null;
Socket clientSocket;
int port = 2222;//Integer.parseInt(args[0]);
try{
sSocket = new ServerSocket(port);
} catch(IOException e){
System.out.println(e);
}
while(true){
try {// listen for a connection from client and accept it.
System.out.println("Server is listenning on host: "
+InetAddress.getLocalHost().getHostAddress() +""
+ " and on port: "
+ port);
clientSocket = sSocket.accept();
System.out.println("Connection accepted");
BufferedReader input = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
// PrintWriter out =
// new PrintWriter(clientSocket.getOutputStream(), true);
PrintStream output = new PrintStream(clientSocket.getOutputStream());
msg = input.readLine();
if(msg != null){
if(msg.charAt(12)=='4'){
System.out.println("reading message "+msg+" ");
output.print("Bye");
sSocket.close();
System.out.println("Server exits");
}else{
if(msg.charAt(12)=='0'){
System.out.println("reading message "+msg+" ");
output.print("OK");
}else if (msg.charAt(12)=='1'){
System.out.println("reading message "+msg+" ");
//Should return IP address
output.print(clientSocket.getInetAddress());
}else if (msg.charAt(12)=='2'){
System.out.println("reading message "+msg+" ");
for(int i = 1; i<=10; ++i){
output.print(i);
output.print(" ");
}
}else if (msg.charAt(12)=='3'){
System.out.println("reading message "+msg+" ");
output.print("GOT IT");
}else{
System.out.println("*******************");
}
}
}
sSocket.close();
System.out.println("Server exits");
}
catch(IOException e) {
System.out.println("accept failed");
System.exit(1);
}
System.out.println("Hello world");
}
}
}
I took some liberties with your code and changed it a bit. It is by no means a perfect version of what you've supplied; however, it should get you pointed in the right direction. These were the problems that were solved:
MyClient was never prompting for user input.
MyServer was sending strings without newlines. MyClient was expecting strings with newlines.
In MyServer, the main socket was being closed at the bottom of the loop. I believe you intended to close the client socket so that the server would loop around and process another client.
In MyServer, you're checking the 13th character of the user's input (because you were indexing the 12th byte (zero based) of the string. I put in brute-force protection against checking the 13th byte of strings that are too short.
Again, I simply corrected certain problems in your code. I may have altered it beyond what your true goals actually are. These examples are intended to get you going on your way...
MyClient.java:
import java.io.*;
import java.net.*;
public class MyClient {
#SuppressWarnings("resource")
public static void main(String[] args) {
// TODO Auto-generated method stub
Socket socket = new Socket();
int port = 2222;
try {
System.out.println("CLient wants to connect on port: " + port);
socket = new Socket(InetAddress.getLocalHost().getHostAddress(), port);
System.out.println("The client is connected");
} catch (UnknownHostException e) {
System.exit(1);
} catch (IOException e) {
System.out.println("connect failed");
System.exit(1);
}
try {
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintStream output = new PrintStream(socket.getOutputStream());
// Get a line of input from the user.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String inputFromUser = br.readLine();
// Send that line of input to MyServer.
output.println(inputFromUser);
// Print out the response from MyServer.
System.out.println("SERVER RESPONSE: " + input.readLine());
socket.close();
System.out.println("Client Exiting");
} catch (IOException e) {
System.out.println(e);
}
}
}
MyServer.java:
import java.io.*;
import java.net.*;
public class MyServer {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
String msg = "";
ServerSocket sSocket = null;
Socket clientSocket;
int port = 2222;// Integer.parseInt(args[0]);
try {
sSocket = new ServerSocket(port);
} catch (IOException e) {
System.out.println(e);
}
while (true) {
try {// listen for a connection from client and accept it.
System.out.println("Server is listenning on host: " + InetAddress.getLocalHost().getHostAddress() + "" + " and on port: "
+ port);
clientSocket = sSocket.accept();
System.out.println("Connection accepted");
BufferedReader input = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
// PrintWriter out =
// new PrintWriter(clientSocket.getOutputStream(), true);
PrintStream output = new PrintStream(clientSocket.getOutputStream());
msg = input.readLine();
if (msg != null) {
if (msg.length() > 12 && msg.charAt(12) == '4') {
System.out.println("reading message " + msg + " ");
output.println("Bye");
System.out.println("Server exits");
} else {
if (msg.length() > 12 && msg.charAt(12) == '0') {
System.out.println("reading message " + msg + " ");
output.println("OK");
} else if (msg.length() > 12 && msg.charAt(12) == '1') {
System.out.println("reading message " + msg + " ");
// Should return IP address
output.println(clientSocket.getInetAddress());
} else if (msg.length() > 12 && msg.charAt(12) == '2') {
System.out.println("reading message " + msg + " ");
for (int i = 1; i <= 10; ++i) {
output.println(i + " ");
}
} else if (msg.length() > 12 && msg.charAt(12) == '3') {
System.out.println("reading message " + msg + " ");
output.println("GOT IT");
} else {
System.out.println("*******************");
// Invalid question from client, I guess.
output.println("HUH?");
}
}
// Make sure output is flushed to client. It will be, but
// just in case...
output.flush();
}
// We're done with this client. Close his socket.
clientSocket.shutdownOutput();
clientSocket.close();
System.out.println("Closed client socket");
}
catch (IOException e) {
System.out.println("accept failed");
e.printStackTrace();
System.exit(1);
}
System.out.println("Hello world");
}
}
}
The problem is that nobody is actually sending any lines. This is what your client does:
output.print(text); //sends null
while ((text = input.readLine()) != null){ //waits to receive a line
This last part is where your client stops because it waits for input that the server never sends. So here is where the server stops:
msg = input.readLine(); //waits to recieve a line
It never reads in null because you didn't send a line (e.g. ending with '\n'). You can easily fix this problem by replacing your output.print() calls with output.println() calls, so that your readers know the line has end and can be read in now.
I have 2 buttons in my client with a button listener each.
In my firt button listener I am sending a String over the socket and I am getting back an array of integers after it is spanwed. No problem there. Here is my code.
public void rollDice() {
try {
DataOutputStream sout1 = new DataOutputStream(socket.getOutputStream());
String line = "dice";
PrintStream out1 = new PrintStream(sout1);
out1.println(line);
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
With the second listener I want t send first a string to put the server into the right state, and after I want to send an integer to continue the process. Here is my code but it doesn't seem to work. Server is printing a random number, even if I send a "2".
public void sendDice() {
try {
DataOutputStream sout2 = new DataOutputStream(socket.getOutputStream());
String line = "pick";
PrintStream out2 = new PrintStream(sout2);
out2.println(line);
out2.write(diceListLength);
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
Here is the server's side.
public void run() {
boolean running = true;
try {
// Create streams for reading / writing lines of text to the socket
DataInputStream input = new DataInputStream(s.getInputStream());
DataInputStream inputInt = new DataInputStream(s.getInputStream());
ObjectOutputStream output = new ObjectOutputStream(s.getOutputStream());
// Print a message:
System.out.println("\nClient from: " + s.getInetAddress() + " port " + s.getPort());
while(running) {
String st = input.readLine();
if (st.equals("dice")) {
for (int i = 0; i < diceRolled.length - number; i++) {
diceRolled[i] = (int) ( 1 + Math.random() * 6);
System.out.print(diceRolled[i] + " ");
}
output.writeObject(diceRolled);
output.reset();
} else if (st.equals("pick")) {
number = inputInt.readInt();
System.out.print(number);
}
}
} catch (IOException e) {
System.out.println("Error: " + e.getMessage());
// Always be sure to close the socket
} finally {
try {
if (s != null) {
System.out.println(s.getLocalSocketAddress() + " closed.");
s.close();
}
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
}
Try setting autoFlush on the PrintStream when you create it... a single integer will not be sent until newline or buffer full.
From java's documentation
autoFlush - A boolean; if true, the output buffer will be flushed whenever a byte array is written, one of the println methods is invoked, or a newline character or byte ('\n') is written
Also useful:
Use line-based messaging, i.e. the second message type can be "pick:4" (check with st.startsWith("pick")) and then parse the integer. With your code, you can easily end up loosing state. (Single-line messages are "pseudo-atomic").
Don't create DataInputStreams in every listener method, make them object variables (same for PrintStreams...). There's no need to (re)create objects in every click.
I'm trying to create a client/server program with java.
when the client connect to the server, the server will show him a message to enter the first value when the user write the first value the server sends him a message to write the sencd value when the user write the second value the server will show him a list of operations ans wait until the client write the number of the operation and then the server will send him the result of this operation.
When I write the program's code and run the server and then the client, it doesn't do any thing the server is blocked from doing anything, also the client.
this is the code I tried :
for the client :
import java.net.*;
import java.util.Scanner;
import java.io.*;
public class Client {
final static String ADRSS = "localhost";
final static int PORT = 1234;
static Socket s = null;
public static void main(String[] args) {
try{
Scanner cn = new Scanner(System.in);
s = new Socket(ADRSS, PORT);
PrintWriter out = new PrintWriter(s.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
in.readLine();
out.println(cn.nextLine());
out.flush();
in.readLine();
out.println(cn.nextLine());
out.flush();
in.readLine();
out.println(cn.nextLine());
out.flush();
System.out.println("Res = " + in.readLine());
out.flush();
}
catch(IOException e){e.printStackTrace();
}
}
}
for the server:
import java.net.*;
import java.io.*;
public class Server {
final static int PORT = 1234;
private static ServerSocket server;
public static void main(String[] args) {
Socket s = null;
try {
server = new ServerSocket(PORT);
s = server.accept();
PrintWriter out = new PrintWriter(s.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
out.println("Donner le premier nombre : ");
out.flush();
double n1 = Double.parseDouble(in.readLine());
out.println("Donner le deuxiéme nombre : ");
out.flush();
double n2 = Double.parseDouble(in.readLine());
out.println("Donner l'op : ");
out.flush();
String choix = in.readLine();
String res = null;
switch(choix){
case "1" :
res = String.valueOf(n1 + n2);
break;
case "2" :
res = String.valueOf(n1 - n2);
break;
case "3" :
res = String.valueOf(n1 * n2);
break;
case "4" :
res = (n2 == 0) ? "Impossible d'éfectuer l'op" : String.valueOf(n1 / n2);
break;
default :
res = "erreur";
}
out.println(res);
out.flush();
}catch(IOException e) {
e.printStackTrace();
}finally{
try{
s.close();
}catch(IOException e){e.printStackTrace();}
}
}
}
PrintWriter doesn't flush output after you use regular print (refer to documentation of PrintWriter). You'd have to flush it manually. However, the real reason is your client waits for a line with newline, which never happens. Changing to out.println on the server side should make this running, also covering the flushes.
first, after every print in the server, add
out.flush();
second, you are asking for nextLine() but printing without \n ,
either add \n to end of each string or use out.println