I'm trying to learn how to use sockets , I wrote a small echo server . I run the code on eclipse , then I go to command prompt and telnet to the port , it should echo back , but instead it gives me this error :
Exception in thread "Thread-0" java.lang.StringIndexOutOfBoundsException: String index out of range: 20
at java.lang.String.getChars(Unknown Source)
at java.io.BufferedWriter.write(Unknown Source)
at echoserver.run(echoserver.java:40)
here is my code :
public final class echoserver extends Thread {
private static final int PORT = 8889;
public static void main(String args[]){
echoserver Echoserver = new echoserver();
if (Echoserver != null){
Echoserver.start();
}
}
public void run (){
try {
ServerSocket server = new ServerSocket(PORT , 1);
while (true) {
Socket client =server.accept();
System.out.println("Client connected");
while (true){
BufferedReader reader =
new BufferedReader(new InputStreamReader(
client.getInputStream()));
System.out.println("Read from client");
String textLine = reader.readLine() + "\n";
if (textLine.equalsIgnoreCase("Exit\n")){
System.out.println("exit invoked, closing client");
break;
}
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(
client.getOutputStream()));
System.out.println("Echo input to client");
writer.write("echo from server:"
+ textLine, 0 , textLine.length() + 18);
writer.flush();
}
client.close();
}
} catch(IOException e){
System.err.println(e);
}
}
}
how can I fix this error ?
This is the problem:
writer.write("echo from server:" + textLine, 0 , textLine.length() + 18);
Your "extra text" is actually 17 characters, not 18. You don't need to specify the offset and length though - you can just use:
writer.write("echo from server:" + textLine);
Related
I'm trying to learn how to do deal with networks in Java 8, and I'm trying to make a client program communicate with a server one. The client is asked a string, which is sent to the server, and the server sends it back in upper characters.
I can't get my server part to work, it simply won't write anything except the fact that the connection is made. Could someone explain what's wrong with my code ?
Server :
public static void main(String[] args) throws IOException {
int listenPort = 9000;
ServerSocket listenSocket = new ServerSocket(listenPort);
Socket socket = listenSocket.accept();
System.out.println("Connexion réussie !");
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
BufferedReader buffer = new BufferedReader(new InputStreamReader(inputStream));
DataOutputStream output = new DataOutputStream(outputStream);
String line = null;
System.out.println("test : " + buffer.readLine());
while((line = buffer.readLine()) != null) {
System.out.println("Message reçu : " + line);
System.out.println("Message envoyé : " + line.toUpperCase());
output.writeUTF(line.toUpperCase());
if(line.equals("stop")) {
socket.close();
listenSocket.close();
}
}
}
Client side :
public static void main(String[] args) throws IOException, UnknownHostException {
Socket socket = new Socket("127.0.0.1", 9000);
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
DataInputStream input = new DataInputStream(inputStream);
DataOutputStream output = new DataOutputStream(outputStream);
BufferedReader buffer = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while((line = buffer.readLine()) != null) {
System.out.println("Message envoyé : " + line);
output.writeChars(line);
System.out.println("Message reçu : " + input.readUTF());
if(line.equals("stop")) {
break;
}
}
socket.close();
}
Inside your client method, you call output.writeChars(line) inside the while loop, this means that you send something to the server after the server send something to you.
Change your client code as follows:
String line = "What a wonderful line";
System.out.println("Message envoyé : " + line);
output.writeChars(line);
while((line = buffer.readLine()) != null) {
System.out.println("Message reçu : " + input.readUTF());
}
I'm creating a simple client-server to use with my Raspberry Pi.
What I'm trying to accomplish is to send "ACKTEMP" for example to the Server using my Client. The servers then calls the serial port (which is my STM32 Nucleo Board btw) with this message I get the temperature back using the serial communication and after that it sends it back to the Client.
My question is, the Nucleo board returns some strings like (TEMP: xx) this works fine until I start sending multiple strings back at once ex. if I send ACKTEMP and want to receive (TEMP: xx ) and "Temperature OK", doing this I only get the first line which is (TEMP: xx ).
So it seems that somewhere in my code I need to change something so it prints out all the lines instead of just one and then stop. Please don't get angry at me if my programming isn't that great I'm a student and trying to understand everything.
public class Client {
/**
* #param args the command line arguments
* #throws java.io.IOException
*/
public static void main(String[] args) throws IOException {
String sentence;
String messageFromServer;
while(true)
{
BufferedReader inFromUser = new BufferedReader( new InputStreamReader(System.in));
try (Socket clientSocket = new Socket("192.168.0.135", 6789)) {
PrintWriter outToServer = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
sentence = inFromUser.readLine();
outToServer.println(sentence + '\n');
messageFromServer = inFromServer.readLine();
System.out.println("FROM SERVER: " + messageFromServer);
clientSocket.close();
}
}
}
}
public class Server {
private static SerialPort serialPort;
/**
* #param args the command line arguments
* #throws java.io.IOException
*/
public static void main(String[] args) throws IOException {
String clientSentence;
String capitalizedSentence;
ServerSocket welcomeSocket = new ServerSocket(6789);
serialPort = new SerialPort("/dev/ttyACM0");
while(true)
{
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
PrintWriter outToClient = new PrintWriter(connectionSocket.getOutputStream(), true);
clientSentence = inFromClient.readLine();
try{
//opening port
serialPort.openPort();
serialPort.setParams(
SerialPort.BAUDRATE_115200,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
//Write string to port
serialPort.writeString(clientSentence + "\n");
System.out.println("String wrote to port, waiting for response..");
try {
Thread.sleep(10); //1000 milliseconds is one second.
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
String buffer = serialPort.readString();
outToClient.println(buffer + '\n');
serialPort.closePort();//Close serial port
}
catch(SerialPortException ex){
System.out.println("Error writing data to port: " + ex);
}
}
// TODO code application logic here
}
}
I used the following to kinda solve this problem. But if someone has a better solution it is very welcome!
What I did is for every string I want a new line, I put a "~" sign in front of the string in my Nucleo STM32 program.
String strArray[] = messageFromServer.split("~");
System.out.println("FROM SERVER: " + strArray[0]);
for(int i = 1; i < strArray.length; ++i)
{
if(messageFromServer.indexOf('~') >= 0)
{
System.out.println("FROM SERVER: " + strArray[i]);
}
}
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'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
I want a client to connect to more than one server. i.e. I want my client to send a number to server1 which squares the number and echoes it back to the client. However I want the client to then send this squared number to a second server listening on a different port.
I'm not sure how to implement this functionality, could I do this through threads or would I just open a second socket to server2?
Here is the code for my client.
import java.io.*;
import java.net.*;
public class ClientA {
public static void main(String[] args) {
String serverhost = "localhost";
int serverport = 6789;
Socket clientSocket = null;
DataOutputStream os = null;
BufferedReader is = null;
try {
clientSocket = new Socket(serverhost, serverport);
os = new DataOutputStream(clientSocket.getOutputStream());
is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host: " + serverhost);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: " + serverhost);
} //end try
if (clientSocket == null || os == null || is == null) {
System.err.println( "An error has occured, please restart." );
return;
} //end if
try {
while ( true ) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String keyboardInput = br.readLine();
os.writeBytes( keyboardInput + "\n" );
int n = Integer.parseInt( keyboardInput );
if ( n == 0 ) {
break;
}
String responseLine = is.readLine();
System.out.println("Server returns its square as: " + responseLine);
}
os.close();
is.close();
clientSocket.close();
} catch (UnknownHostException e) {
System.err.println("Trying to connect to unknown host: " + e);
} catch (IOException e) {
System.err.println("IOException: " + e);
} //end try
} //end main
} //end class
Based on the info you've given, I don't see the need to make it a multi-threaded application as you're only sending (i.e. not receiving) data to the second server when you receive a reply from the first server. Just set up a second socket to the other address and send the data when you get it from the first server.