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.
Related
It's my first time working with UDP channels and I am trying to send back data from the server to the client, but I am getting the following error
java.net.BindException: Cannot assign requested address: no further information
Here is my code
Client
import java.net.*;
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.*;
import javax.swing.JFileChooser;
public class Server {
public static void main(String[] args) {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.printf("\nEscriba el puerto:");
int pto = Integer.parseInt(br.readLine());
System.out.printf("\nMTU:");
int mtu = Integer.parseInt(br.readLine());
// Crea canal
DatagramChannel canal = DatagramChannel.open();
canal.configureBlocking(false);
// Obtén socket asociado al canal
DatagramSocket socket = canal.socket();
// Crea dirección de socket
SocketAddress dir = new InetSocketAddress(pto);
// Asocia la dirección del socket al socket
socket.bind(dir);
// Crea selector
Selector selector = Selector.open();
// Registra selector al canal para escuchar la operación OP_READ
canal.register(selector, SelectionKey.OP_READ);
// Crea buffer
//ByteBuffer buffer = ByteBuffer.allocateDirect(mtu);
ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
int opc=-1;
while (true) {
// bloquea el programa hasta que un canal este listo para ejecutar una operacion
selector.select(5000);// espera 5 segundos por la conexión
// Obtén las llaves asociadas al selector
// C:\Users\datre\OneDrive\Documentos\Eclipse\Redes2\archivos
Set sk = selector.selectedKeys();
Iterator it = sk.iterator();
while (it.hasNext()) {
SelectionKey key = (SelectionKey) it.next();
it.remove();
//key.interestOps(SelectionKey.OP_READ);
if (key.isWritable()) {
System.out.print("It's writable server\n");
if(opc == 1) {//Listar archivos
//ENVIAR OPC
ByteBuffer tamBuffer = ByteBuffer.allocate(4);
tamBuffer.asIntBuffer().put(opc);
tamBuffer.rewind();
SocketAddress client = canal.receive(buffer);
canal.send(tamBuffer,dir);
//LISTA DE ARCHIVOS
System.out.print("Listar archivos\n");
} else if(opc == 2) {//Leer archivo
//ENV OPC
//ENVIAR ARCHIVO
System.out.print("Leer archivos\n");
}
key.interestOps(SelectionKey.OP_READ);
//ready (canal,dir);
//System.exit(0);
//canal.close();
} // if
else if (key.isReadable()) {
System.out.println("Is readable server: getting option");
ByteBuffer b = ByteBuffer.allocate(4);
b.clear();
SocketAddress client = canal.receive(b);
b.flip();
opc = b.getInt();
System.out.println("Opc : " + opc + "\n");
key.interestOps(SelectionKey.OP_WRITE);
} // if
} // while2
} // while
} catch (IOException e) {
System.err.println(e);
} // catch
}// main
private static void ready(DatagramChannel channel, SocketAddress serverAddress) {
System.out.println("Sending filename\n");
try {
String fileName;
File f = new File("C:\\Users\\datre\\OneDrive\\Documentos\\IA\\Estacionamiento1.pdf");
fileName = f.getName();
ByteBuffer buf = ByteBuffer.allocate(1024);
buf.clear();
buf.put(fileName.getBytes());
buf.flip();
channel.send(buf,serverAddress); // Sending the packet with the file name
//channel.write(buf);
//channel.close();
} catch (Exception ex) {
ex.printStackTrace();
System.exit(1);
}
}
}//class
Server
package main;
import java.net.*;
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.*;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileSystemView;
public class Client {
private final static int LIMITE = 100;
public static void main(String[] args) {
boolean bandera = false;
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.printf("Escriba la dirección del servidor:");
String host = br.readLine();
System.out.printf("\nEscriba el puerto:");
int pto = Integer.parseInt(br.readLine());
SocketAddress remoto = new InetSocketAddress(host, pto);
// Crea canal
DatagramChannel canal = DatagramChannel.open();
canal.configureBlocking(false);
// Conecta el canal al socket
canal.connect(remoto);
// Crea selector
Selector selector = Selector.open();
// Registra el selector para esperar la operacion de OP_WRITE
canal.register(selector, SelectionKey.OP_WRITE);
// Crea un buffer de 4 bytes
//ByteBuffer buffer = ByteBuffer.allocateDirect(4);
//Server route
String serverRoute = "C:\\Users\\datre\\OneDrive\\Documentos\\Eclipse\\TrustworthyUDPChannel";
int o=1;
while (true) {
// bloquea el programa hasta que un canal este listo para ejecutar una operacion
selector.select(5000); // espera 5 segundos por la conexión
// Obten el conjunto de keys del selector
Set sk = selector.selectedKeys();
Iterator it = sk.iterator();
while (it.hasNext()) {
SelectionKey key = (SelectionKey) it.next();
it.remove();
//key.interestOps(SelectionKey.OP_READ);
if (key.isReadable()) {
System.out.println("It's readable client");
ByteBuffer b = ByteBuffer.allocate(4);
b.clear();
SocketAddress client = canal.receive(b);
b.flip();
int opc = b.getInt();
System.out.println("Opc : " + opc + "\n");
//createFile (canal,serverRoute);
//canal.close();
} else if (key.isWritable()) {
System.out.println("Is writable client: sending option");
if(o == 1)//Listar archivos
{
ByteBuffer tamBuffer = ByteBuffer.allocate(4);
tamBuffer.asIntBuffer().put(1);
tamBuffer.rewind();
canal.send(tamBuffer,remoto);
} else if(o == 2)// Descargar archivo
{
ByteBuffer tamBuffer = ByteBuffer.allocate(4);
tamBuffer.asIntBuffer().put(2);
tamBuffer.rewind();
canal.send(tamBuffer,remoto);
}
key.interestOps(SelectionKey.OP_READ);
}
} // while
} // while
} catch (Exception e) {
System.err.println(e);
} // catch
}// main
public static void createFile (DatagramChannel channel, String serverRoute){
try{
ByteBuffer buffer = ByteBuffer.allocate(1024);
channel.receive(buffer); // Receive the datagram with the name of the file
System.out.println("Receiving file name");
buffer.flip();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
String fileName = new String(bytes);
File f = new File (serverRoute+"\\"+fileName); // Creating the file
System.out.print(fileName+ "\n" + f + "\n");
FileOutputStream outToFile = new FileOutputStream(f); // Creating the stream through which we write the file content
//receiveFile(outToFile, socket); // Receiving the file
}catch(Exception ex){
ex.printStackTrace();
System.exit(1);
}
}
}// class
I tried to use write instead but I get a different error
java.net.PortUnreachableException
I have a server class and a client class in java.
The fact is that I am testing on localhost and I want my server to answer the request OPTIONS of HTTP.
I do not know what I am doing wrong, my client server receives the request but does not return what I want and I do not understand what I am doing wrong.
I leave here both the client class and the server to see if someone throws some light at this problem.
CLIENT TCP
public class clientetcp {
public static void main(String argv[]) throws IOException {
/*
* Leemos los argumentos del programa para saber a qué
* servidor hay que conectarse.
*/
if (argv.length == 0) {
System.err.println("java clientetcp servidor");
System.exit(1);
}
Socket socket = null;
InetAddress address;
byte[] mensaje_bytes = new byte[256];
String mensaje = "";
try {
/*
* Establecemos una conexión con el servidor en el puerto 6001 y
* enviamos lo que el usuario escribe por teclado. Acabamos con la
* palabra end.
*/
address = InetAddress.getByName(argv[0]);
socket = new Socket(address, 6001);
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
do {
out.writeUTF("GET /index.html HTTP/1.0");
out.writeUTF(""); // blank line separating header & body
out.flush();
String line;
line = in.readUTF();
System.out.println(line);
} while (!mensaje.startsWith("end"));
} catch (Exception e) {
System.err.println(e.getMessage());
System.exit(1);
} finally {
if (socket != null) {
System.out.println("Cerrando socket cliente ...");
socket.close();
}
}
}
}
SERVER TCP
public class servidortcp {
public static void main(String argv[]) throws IOException {
ServerSocket socket = null;
String mensaje;
PrintWriter salida = null;
String salidaOstias;
String pedro;
try {
/*
* Creamos un socket de tipo servidor que escucha en el puerto
* TCP 6001 y espera conexiones de los clientes.
* Este programa recibe lo que viene del socket y lo muestra
* por pantalla.
*/
socket = new ServerSocket(6001);
Socket socket_cli = socket.accept();
DataInputStream in = new DataInputStream(socket_cli.getInputStream());
DataOutputStream out = new DataOutputStream(socket_cli.getOutputStream());
do {
mensaje = in.readUTF();
System.out.println(mensaje);
out.writeUTF("CONTESTO A LO QUE ME HAS DICHO");
} while (1 > 0);
} catch (Exception e) {
if (socket != null) {
System.out.println("Cerrando socket servidor ...");
socket.close();
}
System.err.println(e.getMessage());
System.exit(1);
}
}
}
I did not debug your code, but I think the problem is in the following.
On the server side you should initiate and start a separate thread for every accepted connection. But you are not doing that.
And your server processes all requests in the main thread.
And in this case, until it processes the one iteration (request) of your loop, it won't go to the another iteration, and thus won't process another request.
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.
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.
I'm trying to make an audio loop by a connection server (Java) - Client (Android) in real time. Server (PC / Java) client sends data to the client (mobile / Android) and return.
I put a piece of code to clarify:
- Server
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* This class implements a TCP Server.<p>
*/
public class GTCPServer {
public static final int SERVER_PORT = 4444; // Port number
private boolean running = true; // Boolean to control stream
private ServerSocket serverSocket;
// Input-Output streams:
private DataInputStream dis;
private DataOutputStream dos;
// Buffer:
private byte[] bytes;
private static final int BUFFER_SIZE = 512 * 4; // Size
/**
* Constructor. Starts Server.
*/
public GTCPServer() {
bytes = new byte[BUFFER_SIZE]; // Create buffer
// Put values to test:
bytes[0] = 3;
bytes[BUFFER_SIZE - 1] = 7;
try {
// Create Server Socket and wait connections.
serverSocket = new ServerSocket(SERVER_PORT);
System.out.println("Conecting...");
// Within accept methode we are waiting connection.
// When it's ready, create Client Socket:
Socket client = serverSocket.accept();
System.out.println("Receiving...");
try {
// Streams:
dis = new DataInputStream(client.getInputStream());
dos = new DataOutputStream(client.getOutputStream());
} catch (Exception e) {
System.out.println("Error.");
e.printStackTrace();
}
} catch (Exception e) {
System.out.println("Error.");
e.printStackTrace();
}
} // GTCPServer()
/**
* Send (write) a byte[] buffer within TCP.
* #param buffer - Data.
* #param offset - Position.
* #param count - Number of bytes to write.
*/
public void write(byte[] buffer, int offset, int count) {
try {
dos.write(buffer, offset, count); // Write
} catch (IOException e) {
e.printStackTrace();
}
} // write()
} // GTCPServer
Client:
import android.util.Log;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import com.appacoustic.java.g.G;
public class GTCPClient_A {
public static final String SERVER_IP = "192.168.1.101"; // Server IP (PC)
public static final int SERVER_PORT = 4444; // Port number
private boolean running = true; // Boolean to control stream
// Input-output streams:
private DataInputStream dis;
private DataOutputStream dos;
// Buffer:
private byte[] bytes;
private static final int BUFFER_SIZE = 512 * 4; // Size
/**
* Constructor.
*/
public GTCPClient_A() {
bytes = new byte[BUFFER_SIZE]; // Create buffer
} // GTCPClient_A()
/**
* Execute Thread. It isn't override because we are using a subclass (connectTask) wich extends AsyncTask.
*/
public void run() {
try {
// Get InetAddress (IPv4 Server)
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
Log.e("GTCPClient_A", "Conecting...");
// Create a Socket ti connect with Server:
Socket socket = new Socket(serverAddr, SERVER_PORT);
try {
dis = new DataInputStream(socket.getInputStream());
dos = new DataOutputStream(socket.getOutputStream());
int lap = 0; // Para llevar la cuenta de las vueltas
while (running) {
dis.read(bytes); // Leemos por TCP
System.out.println("IN_ini_["+lap+"]: "+bytes[0]);
System.out.println("IN_fin_["+lap+"]: "+bytes[BUFFER_SIZE - 1]);
G.toc = System.currentTimeMillis();
G.ticToc();
G.tic = G.toc;
dos.write(bytes); // Escribimos por TCP
System.out.println("OUT_ini_["+lap+"]: "+bytes[0]);
System.out.println("OUT_fin_["+lap+"]: "+bytes[BUFFER_SIZE - 1]);
lap++;
}
} catch (Exception e) {
Log.e("GTCP", "SERVIDOR: Error", e);
} finally {
socket.close();
}
} catch (Exception e) {
Log.e("GTCP", "CLIENTE: Error", e);
}
} // run()
} // GTCPClient_A
I have programmed it via Bluetooth and TCP without good results. There is too much delay (around 5 seconds). My surprise was that when trying to deploy the Client in Java instead of Android, does work (the code is almost identical). In fact I speak into the microphone (I scheduled JASIOHost ASIO drivers), from the computer where I have the Server, TCP data travels to another computer within the same WiFi, return and hear real-time perfectly speakers in the Server computer.
So, it appears the problem is something Android. But I what I want is to use a smartphone or tablet as a Client.
I've tested with this line at Client too:
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); // Priority
Find Wear months trying unsuccessfully solution ...
Finally the solution has been UDP. It's faster than TCP or Bluetooth.
I put you code here. Now Server is Android:
public class GUDPServer_A {
private int PORT_NUMBER = 4444; // Nº de puerto de conexión. Usamos el mismo para Servidor y Cliente (para no liar)
private DatagramSocket serverSocket; // Socket Servidor
private DatagramPacket inPacket; // Paquete de entrada
private DatagramPacket outPacket; // Paquete de salida
private boolean running = true; // Booleano para indicar que se está a la escucha del Cliente
// Buffers:
public static final int BUFFER_SIZE = 1024 * 4;
public static byte[] bytes_in;
public static byte[] bytes_out;
public GUDPServer_A() {
bytes_in = new byte[BUFFER_SIZE];
bytes_out = new byte[BUFFER_SIZE];
try {
serverSocket = new DatagramSocket(PORT_NUMBER); // Sólo se hace una vez ya que siempre estamos mandando por el mismo puerto
System.out.println("Servidor UDP en marcha.");
} catch (SocketException e) {
System.out.println("Socket: "+e.getMessage());
} catch (IOException e) {
System.out.println("IO: "+e.getMessage());
}
} // GUDPServer_A()
/**
* Ejecución del hilo. El método no está sobreescrito porque usamos una subclase (connectTask) que extiende de AsyncTask.
*/
public void run() {
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); // Le damos prioridad "-19" al Thread (Lo máximo es -20)
int lap = 0; // Para llevar la cuenta de las vueltas
while (running) {
read(bytes_in); // Recibimos el paquete desde UDP
// Procesamos (de momento lo dejamos igual, simplemente clonamos):
bytes_out = bytes_in.clone();
G.toc = System.currentTimeMillis();
G.ticToc();
G.tic = G.toc;
write(bytes_out); // Enviamos el paquete de vuelta
Log.d("Vuelta:", ""+lap);
lap++;
}
} // run()
/**
* Envía (escribe) un buffer de bytes por UDP.
* #param buffer - La memoria intermedia donde se almacenan los datos a enviar.
*/
public void write(byte[] buffer) {
outPacket = new DatagramPacket(buffer, inPacket.getLength(), inPacket.getAddress(), inPacket.getPort());
try {
serverSocket.send(outPacket); // Enviamos el paquete
} catch (IOException e) {
e.printStackTrace();
}
} // write()
/**
* Recibe (lee) un buffer de bytes por UDP.
* #param buffer - La memoria intermedia donde se almacenan los datos a recibir.
*/
public void read(byte[] buffer) {
inPacket = new DatagramPacket(buffer, buffer.length);
try {
serverSocket.receive(inPacket); // Recibimos el paquete
} catch (IOException e) {
e.printStackTrace();
}
} // read()
/**
* Cierra la conexión.
*/
public void stop() {
if (serverSocket != null) {
serverSocket.close();
}
} // stop()
} // GUDPServer_A
And Client is Java:
public class GUDPClient {
private int PORT_NUMBER = 4444; // Nº de puerto de conexión. Usamos el mismo para Servidor y Cliente (para no liar)
private DatagramSocket clientSocket; // Socket Cliente
private DatagramPacket inPacket; // Paquete de entrada
private DatagramPacket outPacket; // Paquete de salida
private InetAddress host; // Dirección IP del Servidor (LG L5)
public static final String IP_LG = "192.168.1.102"; // IP del Servidor (LG L5)
public static final String IP_TABLET = "192.168.1.105"; // IP del Servidor (Tablet)
/**
* Constructor.
*/
public GUDPClient() {
try {
clientSocket = new DatagramSocket(); // No hace falta darle un nº de puerto (se lo damos al paquete)
host = InetAddress.getByName(IP_LG); // Obtenemos el host del Servidor (LG L5)
//host = InetAddress.getByName(IP_TABLET); // Obtenemos el host del Servidor (Tablet)
System.out.println("Cliente UDP conectado.");
} catch (SocketException e) {
System.out.println("Socket: "+e.getMessage());
} catch (IOException e) {
System.out.println("IO: "+e.getMessage());
}
} // GUDPClient()
/**
* Envía (escribe) un buffer de bytes por UDP.
* #param buffer - La memoria intermedia donde se almacenan los datos a enviar.
*/
public void write(byte[] buffer) {
outPacket = new DatagramPacket(buffer, buffer.length, host, PORT_NUMBER);
try {
clientSocket.send(outPacket); // Enviamos el paquete por UDP
} catch (IOException e) {
e.printStackTrace();
}
} // write()
/**
* Recibe (lee) un buffer de bytes por UDP.
* #param buffer - La memoria intermedia donde se almacenan los datos a recibir.
*/
public void read(byte[] buffer) {
inPacket = new DatagramPacket(buffer, buffer.length);
try {
clientSocket.receive(inPacket); // Recibimos el paquete procesado desde UDP
} catch (IOException e) {
e.printStackTrace();
}
} // read()
/**
* Cierra la conexión.
*/
public void stop() {
if (clientSocket != null) {
clientSocket.close();
}
} // stop()
} // GUDPClient
One important thing is setting fast Threads.
Android: android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
Java: thread.setPriority(Thread.MAX_PRIORITY);
It seems like you are using tcp/ip for this purpose.
You should you UDP for audio.