I'm trying to create a simple calculator using sockets but when I send numbers to the server I have a problem: for example if I want to add 2 numbers x=13 and y=2 the server receives x=64 and y=42 and the result is 106. I think that the problem is with the method write, I have no problem with strings but with numbers I dont know how to work. I'm a beginner, thanks for the help.
SERVER
package calcolatrice;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
ServerSocket server;
Socket msocket;
BufferedReader in;
DataOutputStream out;
public Socket attendi() {
try {
//creo il server sulla porta ****
System.out.println("Server in esecuzione..");
server = new ServerSocket(1122);
//accetto eventuale connessione da parte del client
msocket = server.accept();
System.out.println("Client connesso con successo! ");
//chiudo la connessione per evitare altre connessioni
server.close();
//inizializzo gli stream per consentire la comunicazione
out = new DataOutputStream(msocket.getOutputStream());
in = new BufferedReader(new InputStreamReader(msocket.getInputStream()));
} catch (IOException e) {
System.out.println(e.getMessage());
System.out.println("Errore durante l'istanza del server");
System.exit(1);
}
return msocket;
}
public void calcola(){
try{
double x;
double y;
double risultato=0;
//leggo la scelta e in base a quella eseguo le operazioni
int scelta = in.read();
//accetto prima i numeri
x = in.read();
System.out.println("x "+x);
y = in.read();
System.out.println("y "+y);
switch (scelta){
case 1:
System.out.println("Scelta: "+scelta);
//somma
risultato = x+y;
}
System.out.println("Risultato: "+risultato);
}catch (Exception e){
}
}
public static void main(String args[]) {
Server myServer = new Server();
myServer.attendi();
myServer.calcola();
}
}
CLIENT
package calcolatrice;
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
public class Client{
Socket socket;
protected int porta = 1122;
String nomeServer = "localhost";
//stream per comunicare
DataOutputStream out;
BufferedReader in;
Scanner input = new Scanner(System.in);
public Socket connetti(){
try {
System.out.println("Client avviato..");
//creo il socket per connettermi al server
socket = new Socket(nomeServer, porta);
System.out.println("Client connesso con successo al server ' "+nomeServer+" ' sulla porta: "+porta);
//inizializzo gli stream per consentire la comunicazione
out = new DataOutputStream(socket.getOutputStream());
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (Exception e){
System.out.println("Errore, impossibile connettersi");
System.exit(1);
}
return socket;
}
//menu per scelta operazioni
private void menu(){
try{
System.out.println("---Calcolatrice---");
System.out.println("[1.Somma \t 2.Differenza \t 3.Moltiplicazione \t 4.Divisione]");
System.out.println("0.ESCI");
} catch (Exception e){
System.out.println("Errore");
}
}
//funzione per comunicare
public void comunica(){
try {
int scelta=0;
//do{
menu();
System.out.println("Inserire operazione ");
scelta = input.nextInt();
//invio la scelta al server
//out.writeByte(scelta);
out.write(scelta);
//Inserisco i numeri e li spedisco al server
System.out.println("Inserisci primo numero.");
double x = input.nextDouble();
out.writeDouble(x);
System.out.println("Inserisci secondo numero.");
double y = input.nextDouble();
out.writeDouble(y);
//}
//while(scelta != 0);
}catch (IOException e){
}
}
public static void main(String args[]){
Client myClient = new Client();
myClient.connetti();
myClient.comunica();
}
}
The original code uses a BufferedReader which I think might be the cause of the problem. If you replace this with a DataInputStream, you will be able to call readInt() and readDouble() methods.
Replace BufferedReader in; with DataInputStream in;. It can be constructed in a similar way to the existing code using:
in = new DataInputStream(msocket.getInputStream());
Then replace all calls to in.read() with either in.readInt() or in.readDouble() as appropriate.
I got it to work by removing the DataOutputStream object (out) then I added the following line to the comunica() method:
System.out.println(x + "," + y);
Re-running your code I got the output:
Client avviato..
Client connesso con successo al server ' localhost ' sulla porta: 1122
---Calcolatrice---
[1.Somma 2.Differenza 3.Moltiplicazione 4.Divisione]
0.ESCI
Inserire operazione
1
Inserisci primo numero.
2
Inserisci secondo numero.
3
2.0,3.0
Your code is reading in the numbers OK.
Related
The problem is quite simple but I haven't found the solution yet (Sorry for bad english, I don't have many opportunities to write in english... so broken english expected, be warned).
I have a simple UDP java code (client) that sends a message via datagrampacket to a another java code (server) and prints the message recieved. The problem is that the first sent message goes well (it prints the data I have sent) but the others packets transforms from 26 bytes to 15 bytes, and this isn't a problem on the variables, nor the client (I guess) because when I print the data.lenght of the message I send this is always 26 (like it should be).
This is my code:
Client:
import java.io.IOException; import java.net.DatagramPacket;
import java.net.DatagramSocket; import java.net.InetAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.TimeUnit;
public class cliente {
public static final void main(final String[] args) {
InetAddress direccion; DatagramPacket p; byte[] data = new byte[5024];
DatagramPacket recibido = new DatagramPacket(data, data.length);
while(true){
for(int i=0, k=5; i<k;i++) {
String[] SensoresId = new String[] {"001", "002", "003", "004", "005"};
try {
direccion = InetAddress.getByName("localhost"); //get local host address
//Grabbing ID of sensor
String Sen_Id = SensoresId[i];
//Taking Date of execution and hour
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");
Date date = new Date();
String fecha_ahora = new String(dateFormat.format(date));
//random parameter
Random random = new Random();
int numero_rand = random.nextInt(101);
String medicion = String.valueOf(numero_rand);
//joining all variables in the message to send
String mensaje = Sen_Id + "," + medicion + "," + fecha_ahora;
try(DatagramSocket client = new DatagramSocket()) {
data = mensaje.getBytes(); //allocating the data
p = new DatagramPacket(data, data.length, direccion, 9984); //create package
System.out.println("enviando la data...");//sending the data...
client.send(p); //send message
client.setSoTimeout(5000); //waiting a to a timeout
while(true) {
try {
//getting the respond message
client.receive(recibido);
String mensaje_de_vuelta = "recibiendo de:" + recibido.getAddress() + "," + "mensaje:" + new String(recibido.getData());
String respuesta = new String(recibido.getData());
System.out.println(mensaje_de_vuelta + "\n");
//Not so important code (work in process)
if(respuesta == "duplicados" || respuesta == "OK") {
break;
}
client.close(); //I tried to close the client in hope that will fix it but no
break;
}catch(SocketTimeoutException e) {
System.out.println("Se acabo tu tiempo!" + e);
client.close();
}
}
}
} catch (SocketException e1) {
System.out.println("Error en socket" + e1);
}catch (IOException e2) {
e2.printStackTrace();
}
}
try {
System.out.println("Esperando 5 segundos...");
TimeUnit.SECONDS.sleep(5);
}catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
}
Server:
import java.io.IOException; import java.net.DatagramPacket;
import java.net.DatagramSocket; import java.net.InetAddress;
import java.net.SocketException;
public class servidor {
public static final void main(final String[] args) {
DatagramPacket p; byte[] data = new byte[5024];
try(DatagramSocket server = new DatagramSocket(9984)) {
while(true) {
p = new DatagramPacket(data, data.length); //create package
server.receive(p); //wait for and receive package
System.out.println("Se recibio tu mensaje");
//System.out.println("New message " + p.getSocketAddress());
String mensaje_cliente = new String(p.getData(),0,p.getLength());
System.out.println(p.getLength());
//Make a print to see recieve message
System.out.println(mensaje_cliente);
//Obtaining adresses
int puertoCliente = p.getPort();
InetAddress direccion = p.getAddress();
//preparing the respond
String mensaje_vuelta = "Hola como esta?";
data = mensaje_vuelta.getBytes();
DatagramPacket respuesta = new DatagramPacket(data, data.length, direccion, puertoCliente);
//sending respond
System.out.println("Enviando respuesta al cliente...");
server.send(respuesta);
}
} catch (SocketException e) {
e.printStackTrace();
} catch(IOException e1) {
e1.printStackTrace();
}
}
}
Result:
Se recibio tu mensaje
26
001,18,2020/11/18 09:35:30
Enviando respuesta al cliente...
Se recibio tu mensaje
15
002,14,2020/11/
Enviando respuesta al cliente...
Se recibio tu mensaje
15
003,36,2020/11/
Enviando respuesta al cliente...
Se recibio tu mensaje
15
004,59,2020/11/
Enviando respuesta al cliente...
Se recibio tu mensaje
15
005,84,2020/11/
Enviando respuesta al cliente...
As you can see the message lenght decreases from 26 to 15, and that makes the message split in half. <--that's my problem.
Thanks in advance for the responses.
Have a great day.
self explainatory, server handle the client and recognize the connection, but they can't communicate yet. here's the code:
Server Class:
import java.io.*;
import java.net.*;
import java.util.*;
public class Server{
private final int PORT=8080;
public BufferedReader fromClient;
public PrintWriter toClient;
public ServerSocket server;
public Socket clientSocketHandler;
public Server(){ //constructor
if(startServer())
System.out.println("Server Avviato...");
else
System.out.println("Errore nell'avvio del server...");
}
private boolean startServer(){
try{
server = new ServerSocket(PORT);
}catch(IOException e){
e.printStackTrace();
return false;
}
return true;
}
public void runServer(){
try{
System.out.println("Server in ascolto sulla porta " + PORT + " ...");
clientSocketHandler = server.accept();
System.out.println("Client Connesso...");
InputStreamReader isr = new InputStreamReader(clientSocketHandler.getInputStream());
fromClient = new BufferedReader(isr);
OutputStreamWriter osr = new OutputStreamWriter(clientSocketHandler.getOutputStream());
BufferedWriter bw = new BufferedWriter(osr);
toClient = new PrintWriter(bw);
}catch(IOException e){
e.printStackTrace();
}
}
}
MainServer Class:
import java.lang.*;
import java.io.*;
import java.net.*;
public class MainServer{
public static void main(String args[]){
Server s1 = new Server();
s1.runServer();
float n1,n2;
String op;
try{
s1.toClient.println("comunicazione da server");
System.out.println("Aspettando i numeri...");
n1=Float.parseFloat(s1.fromClient.readLine());
n2=Float.parseFloat(s1.fromClient.readLine());
System.out.println("Numeri accettati");
System.out.println("Aspettando operatore...");
op=s1.fromClient.readLine();
System.out.println("Operatore accettato");
}catch(IOException e){
e.printStackTrace();
}
}
}
Client class:
import java.io.*;
import java.net.*;
public class Client{
private final int PORT=8080;
private InetAddress address = InetAddress.getLoopbackAddress();
public PrintWriter toServer;
public BufferedReader fromServer;
public BufferedWriter bw;
public Socket client;
public Client(){
if(startClient())
System.out.println("Connesso al Server...");
else
System.out.println("Errore nella connessione...");
}
private boolean startClient(){
try{
client = new Socket(address, PORT);
OutputStreamWriter osw = new OutputStreamWriter(client.getOutputStream());
bw = new BufferedWriter(osw);
toServer = new PrintWriter(bw);
InputStreamReader isr = new InputStreamReader(client.getInputStream());
fromServer = new BufferedReader(isr);
}catch(IOException e){
e.printStackTrace();
return false;
}
return true;
}
}
MainClient Class:
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class MainClient{
public static void main(String args[]){
Client c = new Client();
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader kBoard = new BufferedReader(isr);
String n1,n2,op;
try{
System.out.println(c.fromServer.readLine());
System.out.println("Inserisci il primo numero");
n1=kBoard.readLine();
System.out.println("Inserisci il Secondo numero");
n2=kBoard.readLine();
System.out.println("Passando i valori al server");
c.toServer.println(n1);
c.toServer.println(n2);
System.out.println("Inserisci l'operatore [+,-,/,*]");
op = kBoard.readLine();
System.out.println("Passando i valori al server");
c.toServer.println(op);
}catch(IOException e){
e.printStackTrace();
}
}
}
Sorry for the italian Strings.
It client stucks at "Connesso al Server..." and Server stucks at "Aspettando i numeri"
Help me!! :)
You should make a infinite loop (while(true) {...}) in the server socket method runServer in order to accept client sockets. Without it just doesn't listens!
In order to process more than one client you should also make it multi-threading; i.e. each time a new client is accepted launch a new thread to process the request.
Should help you out. Have a nice day...
I'm doing a school project where we are supposed to create a simplefied Hotel booking system and then use it with a server/client communication.
Since I wanted to push the project a bit and do a multithreaded program, I've got a Socket Exception that I'm not sure how to handle. I've searched everywhere for an answer and I know that the exception occours because I'm trying to use a socket that has been closed. But from what I've read on Oracle-docs, their example is doing that as well.
So, is this actually Ok, just that I need to handle the exception? Cause my code runs fine, I just see the exceptions since I've put e.printStackTrace(); in my catch.
My Client class:
package client;
import java.io.*;
import java.net.Socket;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Scanner;
public class Client {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
try {
Socket client = new Socket("localhost", 6066);
//System.out.println("Just connected to " + client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
InputStream inFromServer = client.getInputStream();
DataInputStream in = new DataInputStream(inFromServer);
LocalDate localDate = LocalDate.now();
String date = DateTimeFormatter.ofPattern("yyy/MM/dd").format(localDate);
System.out.println(in.readUTF());
System.out.print("Namn: ");
String name = sc.nextLine();
System.out.print("Ålder: ");
String age = sc.nextLine();
out.writeUTF(name);
out.writeUTF(age);
out.writeUTF(date);
System.out.println(in.readUTF());
client.close();
}catch(IOException e) {
e.printStackTrace();
}
}
}
And my Server class:
package server;
import java.io.IOException;
import java.net.*;
public class Server {
public static void main(String [] args) throws IOException {
int port = 6066;
ServerSocket server = new ServerSocket(port);
while(true) {
System.out.println("Listening for client..");
try {
Socket connectedClient = server.accept();
ClientHandle ch = new ClientHandle(connectedClient);
Thread t = new Thread((Runnable) ch);
t.start();
}catch (IOException e) {
}
}
}
}
And then my ClientHandle class which has the run() for the server-side:
package server;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.*;
import resources.*;
public class ClientHandle implements Runnable{
Socket connectedClient;
DataInputStream in;
DataOutputStream out;
public ClientHandle(Socket connectedClient) {
this.connectedClient = connectedClient;
try{
this.in = new DataInputStream(this.connectedClient.getInputStream());
this.out = new DataOutputStream(this.connectedClient.getOutputStream());
}catch(IOException ex) {
}
}
Hotel hotel = new Hotel();
Ticket yourTicket = new Ticket();
Server server = new Server();
#Override
public void run() {
while (true) {
try {
InetAddress host = InetAddress.getLocalHost();
System.out.println("Client " + host + " has connected.");
out.writeUTF("Välkommen till Hotel Gisslevik!\nVänligen fyll i nedan information för att slutföra din bokning.\n");
String yourName = in.readUTF();
String age = in.readUTF();
int yourAge = Integer.parseInt(age);
String date = in.readUTF();
yourTicket.setDate(date);
Person guest = new Person(yourName, yourAge);
hotel.setRooms();
Integer room = hotel.getRoom();
String rent = "J";
if (rent.indexOf("J") >= 0) {
yourTicket.setId(yourName);
if (hotel.checkIn(guest, room, yourTicket.getId(), yourTicket.getDate())) {
String yourId = yourTicket.getId();
out.writeUTF("\nDitt rum är nu bokat den " + date + ". \nBokningsnummer: " + yourId);
}
}
out.flush();
connectedClient.close();
}catch (EOFException e) {
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
}
If I just comment e.printStackTrace(); the exceptions doesn't show, but I would like to know how to handle them (if they should be handled). I've been searching the internet for days and checked out tutorials, but I don't find a proper answer to this.
I really appreciate any help you can provide.
Handle java.net.SocketException: Socket closed
Don't close the socket and then continue to use it.
when multithreading?
Irrelevant.
You have connectedClient.close() inside your while (true) loop. Solution: move it outside.
I made a program to do simple operations in Local Host, such as type a number and a power, calculate it in another class and send it back, but I want to know how to do this with a virtual machine so I can obtain data from the client, here's my code for the virtual client and the connection to it:
package clientedatos;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Scanner;
public class ClienteDatos
{
public static void main(String[] args) throws Exception
{
int Valor, Potencia;
Scanner Sc = new Scanner(System.in);
System.out.println("Capture un valor que sera elevado a una potencia");
Valor=Sc.nextInt();
System.out.println("Capture la potencia");
Potencia=Sc.nextInt();
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
Socket s = null;
try
{
// instancio el server con la IP y el PORT
s = new Socket("127.0.0.1",5432);
oos = new ObjectOutputStream(s.getOutputStream());
ois = new ObjectInputStream(s.getInputStream());
// envio un nombre
oos.writeObject(Valor+","+Potencia);
long a=System.currentTimeMillis();
// recibo la respuesta (el saludo personalizado)
String ret = (String)ois.readObject();
long b=System.currentTimeMillis();
String[] respuesta = ret.split(",");
long Latencia = (a-b)-Integer.parseInt(respuesta[1]);
// muestro la respuesta que envio el server
System.out.println(respuesta[0]);
System.out.println("La latencia es: "+Latencia);
}
catch(Exception ex)
{
ex.printStackTrace();
}
finally
{
if( ois != null ) ois.close();
if( oos != null ) oos.close();
if( s != null ) s.close();
}
}
}
And here's the code for the Server:
package datosclientes;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class ServerDatos
{
public static void main(String[] args) throws Exception
{
ObjectInputStream ois = null;
ObjectOutputStream oos = null;
Socket s = null;
ServerSocket ss = new ServerSocket(5432);
while( true )
{
try
{
// el ServerSocket me da el Socket
s = ss.accept();
// informacion en la consola
System.out.println("Se conectaron desde la IP: "
+s.getInetAddress());
// enmascaro la entrada y salida de bytes
ois = new ObjectInputStream( s.getInputStream() );
oos = new ObjectOutputStream( s.getOutputStream() );
// leo el nombre que envia el cliente
long A=System.currentTimeMillis();
String ValorStr = (String)ois.readObject();
String[] input = ValorStr.split(",");
int Valor = Integer.parseInt(input[0]);
int Potencia = Integer.parseInt(input[1]);
// armo el saludo personalizado que le quiero enviar
for(int i = 1;i<Potencia; i++){
Valor=Valor*Valor;
}
long B=System.currentTimeMillis();
String saludo = "El resultado es "+Valor+","+(A-B);
// envio el saludo al cliente
oos.writeObject(saludo);
System.out.println("Resultado enviado...");
}
catch(Exception ex)
{
ex.printStackTrace();
}
finally
{
if( oos !=null ) oos.close();
if( ois !=null ) ois.close();
if( s != null ) s.close();
System.out.println("Conexion cerrada!");
}
}
}
}
This is no different from connecting to a physical host. You need to have a network connection between the two machines - which is part of the virtual machine setup - and then specify the appropriate ip address (or hostname if available via name resolution mechanisms) and port instead of 127.0.0.1.
For command line tools you commonly read the target address from a parameter.
server socket is created and waits for a client to connect. Once the client connects, it has to guess the number that was generated on the server. If not, will ask the number continuously.
SERVER:
package pruebas;
import java.net.*;
import java.io.*;
public class server {
public static void main(String[] args) throws IOException {
int num_aleatorio = generarNumAleatorio(); //genera un número aleatorio
int num_usuario=0;
int intentos=0;
boolean adivinado = false;
System.out.println("Generated number: " + num_aleatorio);
ServerSocket server_socket = null; //server_socket de tipo sevidor
Socket client_socket = null; //server_socket tipo cliente
System.out.println("Server OK...\nWaiting players...");
try {
server_socket = new ServerSocket(1111); //nuevo socket servidor con puerto 1111
client_socket = server_socket.accept(); //El servidor acepta el socket cliente
System.out.println("El cliente se ha conectado");
//Declaramos los emisores/receptores
DataInputStream in = new DataInputStream(new BufferedInputStream(client_socket.getInputStream()));
DataOutputStream out = new DataOutputStream(new BufferedOutputStream(client_socket.getOutputStream()));
while(true)
{
if(!adivinado){
out.writeBoolean(false);
num_usuario = in.readInt(); //recoger num del usuario
if(num_usuario == num_aleatorio){
adivinado = true;
out.writeBoolean(true);
}
else if(num_usuario > num_aleatorio) out.writeUTF("El número es menor que " + num_usuario);
else if(num_usuario < num_aleatorio) out.writeUTF("El número es mayor que " + num_usuario);
intentos++;
}
else if(adivinado) out.writeUTF("Has acertado! Con un total de " + intentos + " intentos.");
else
{
server_socket.close();
client_socket.close();
}
}
} catch (IOException e) {
System.out.println("Exception caught when trying to listen on port 1111 or listening for a connection");
System.out.println(e.getMessage());
}
}
private static int generarNumAleatorio()
{
return (int)(Math.random() * 100 +1); //del 0 al 99 (el +1 hace que sea del 1 al 100)
}
}
CLIENT:
package pruebas;
import java.io.*;
import java.net.*;
import java.util.InputMismatchException;
import java.util.Scanner;
public class client {
public static void main(String[] args) throws IOException {
Scanner teclado = new Scanner(System.in);
System.out.println("Adivina el número!");
int num_usuario=0;
boolean errores=false;
boolean adivinado=false;
Socket client_socket = null;
try{
client_socket = new Socket("127.0.0.1", 1111); //se crea un socket
//Declaramos los emisores/receptores
DataInputStream in = new DataInputStream(new BufferedInputStream(client_socket.getInputStream()));
DataOutputStream out = new DataOutputStream(new BufferedOutputStream(client_socket.getOutputStream()));
do{
//PEDIR NUMERO AL USUARIO
do{
errores = false;
try{
System.out.print("Introduce un número del 1-99:");
num_usuario = teclado.nextInt();
}catch(InputMismatchException e){
System.out.print("\n Introduce valores numéricos!\n");
errores = true;
teclado.nextLine(); //evitar bucle de error
}
}while(errores);
out.writeInt(num_usuario); //enviar num_usuario al server
out.flush();
adivinado = in.readBoolean();
System.out.println(in.readUTF());//mostrar resultado del server
}while(!adivinado);
} catch (UnknownHostException e) {
System.err.println("Don't know about host ");
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to "+ e);
System.exit(1);
}
finally
{
teclado.close();
client_socket.close();
}
}
}
The program asking for the number, but the program will not return if it is greater or less, why?
Thanks in advance
The loop in the server has many problems in it:
You start by sending false to the client, even before the client makes a guess
Whenever the guess is incorrect, you send a string message followed by a false value. The client expects the opposite order.
Whenever the guess is correct, the server enters an infinite loop sending the "Has acertado..." text to the client.