Reputation: 910
I have a few clients trying to connect to a java program using a socket, so when two connections arrives at the same time one of them are not received the response, I read in many posts that there is a problem when the server send the response at the same time to many clients so I try to make a synchronized block of that response but it doesn't work
I create a ServerSocket, wait until a connection is made and create a thread
public class Server{
private static ServerSocket serverSocket;
static int PORT = 8080;
public static void main(String [] args){
try {
serverSocket = new ServerSocket(PORT);
while(true){
ServerThread obj=new ServerThread(serverSocket.accept());
Thread thread =new Thread(obj);
thread.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
On the thread I read the input that the client is sending, decrypt that input, process it, encrypt the response and send that response to the client
public class ServerThread extends Thread{
final static Logger logger = Logger.getLogger(ServerThread.class);
private Aes aes;
static int SIZE=500;
static int TIMEOUT=10000;
private Socket s;
private ServerSocket serverSocket;
public ServerThread(Socket s) {
this.s=s;
}
public void run() {
try{
System.out.println(this.getName());
System.out.println("Just connected to " + s.getRemoteSocketAddress());
DataInputStream in = new DataInputStream(s.getInputStream());
s.setSoTimeout(TIMEOUT);
int equis = 0;
StringBuilder builder=new StringBuilder();
while((equis=in.readByte())>0){
builder.append(Character.toChars(equis));
}
String valor=builder.toString();
System.out.println(valor);
valor=Encriptacion("decrypt", valor);
System.out.println(valor);
String[] datos = valor.split("\\|");
String tarjeta=datos[0];
double monto=(Double.parseDouble(datos[1].isEmpty()?"0":datos[1]))/100;
int tipoTransaccion=Integer.parseInt(datos[2].isEmpty()?"0":datos[2]);
String numeroSerieTPV=datos[3];
String usuario=datos[4];
String contrasena=datos[5];
String llave=datos[6];
String referencia=datos[7];
String referencia2=datos[8];
int plazo=Integer.parseInt(datos[9].isEmpty()?"0":datos[9]);
int cvv=Integer.parseInt(datos[10].isEmpty()?"0":datos[10]);
int cvv2=Integer.parseInt(datos[11].isEmpty()?"0":datos[11]);
int transaccionId=Integer.parseInt(datos[12].isEmpty()?"0":datos[12]);
int comercioId=Integer.parseInt(datos[13].isEmpty()?"0":datos[13]);
int terminalId=Integer.parseInt(datos[14].isEmpty()?"0":datos[14].trim());
StringBuffer buf = new StringBuffer();
buf.append("");
Transacciones transacciones=new Transacciones();
if(tipoTransaccion==1){
transacciones.compra(tarjeta, monto, comercioId, plazo, terminalId,llave);
}else if(tipoTransaccion==2){
transacciones.pago(tarjeta, monto, comercioId, terminalId,llave);
}else if(tipoTransaccion==3){
transacciones.disposicion(tarjeta, monto,comercioId, plazo, terminalId,llave);
}else if(tipoTransaccion==4){
transacciones.reporte(comercioId, terminalId,llave);
}else if(tipoTransaccion==5){
transacciones.validarUsuario(usuario, contrasena, numeroSerieTPV);
}else if(tipoTransaccion==6){
transacciones.confirmacion(transaccionId);
return;
}else{
transacciones.getEnvioDatos().setCodigoError("0");
transacciones.getEnvioDatos().setDescripcionError("Tipo de transaccion invalido.");
}
buf.append(transacciones.getEnvioDatos().getCodigoError()+"|"
+transacciones.getEnvioDatos().getDescripcionError()+"|"
+transacciones.getEnvioDatos().getFecha()+"|"
+transacciones.getEnvioDatos().getHora()+"|"
+transacciones.getEnvioDatos().getNombreCliente()+"|"
+transacciones.getEnvioDatos().getClave()+"|"
+transacciones.getEnvioDatos().getPromesas()+"|"
+transacciones.getEnvioDatos().getReporte()+"|"
+transacciones.getEnvioDatos().getLlave()+"|"
+transacciones.getEnvioDatos().getTerminalBloqueada()+"|"
+transacciones.getEnvioDatos().getTerminalEstatus()+"|"
+transacciones.getEnvioDatos().getTerminalId()+"|"
+transacciones.getEnvioDatos().getComercioId()+"|"
+transacciones.getEnvioDatos().getTerminalNombre()+"|"
+transacciones.getEnvioDatos().getSucursalId()+"|"
+transacciones.getEnvioDatos().getNombresucursal()+"|"
+transacciones.getEnvioDatos().getDireccionSucursal()+"|"
+transacciones.getEnvioDatos().getPermisoCompra()+"|"
+transacciones.getEnvioDatos().getPermisoDisposicion()+"|"
+transacciones.getEnvioDatos().getPermisoPago()+"|"
+transacciones.getEnvioDatos().getPermisoTiempoAire()+"|"
+transacciones.getEnvioDatos().getCompraMinima()+"|"
+transacciones.getEnvioDatos().getDisposicionMinima()+"|"
+transacciones.getEnvioDatos().getDisposicionMaxima()+"|"
+transacciones.getEnvioDatos().getPlazos()+"|");
if(buf.length()<SIZE) {
while(buf.length()<SIZE)
buf.append("*");
}
String str=buf.toString();
System.out.println(str);
String x=Encriptacion("encrypt", str);
System.out.println(this.getName());
System.out.println("Just connected to " + s.getRemoteSocketAddress());
DataOutputStream out=null;
synchronized(this){
out = new DataOutputStream(s.getOutputStream());
out.write(x.getBytes(Charset.forName("UTF-8")), 0, x.length());
System.out.println(x);
out.flush();
out.close();
}
s.close;
in.close();
} catch(SocketTimeoutException e) {
System.out.println(e);
} catch(IOException e) {
System.out.println(e);
}catch(Throwable e){
System.out.println(e);
}finally{
}
}
}
I read a lot of web pages but I can't find an answer, Could someone help me to find my error?,
Thanks in advance
Edited:
I change my code :
public class Server{
public static void main(String [] args){
ServerThread obj=new ServerThread();
}
}
public class ServerThread {
final static Logger logger = Logger.getLogger(ServerThread.class);
static int SIZE=500;
static int TIMEOUT=10000;
private Socket s;
private static ServerSocket serverSocket;
static int PORT = 8080;
private Object lock=new Object();
public ServerThread() {
try {
serverSocket = new ServerSocket(PORT);
} catch (IOException e) {
e.printStackTrace();
}
for(int i=0;i<50;i++){
try {
Thread accept = new Thread() {
public void run(){
try {
s=serverSocket.accept();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(this.getName());
process();
}};
accept.start();
accept.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void process(){
try{
System.out.println("Just connected to " + s.getRemoteSocketAddress());
DataInputStream in = new DataInputStream(s.getInputStream());
s.setSoTimeout(TIMEOUT);
int equis = 0;
StringBuilder builder=new StringBuilder();
while((equis=in.readByte())>0){
builder.append(Character.toChars(equis));
}
String valor=builder.toString();
System.out.println(valor);
valor=encriptacion("decrypt", valor);
System.out.println(valor);
String[] datos = valor.split("\\|");
String tarjeta=datos[0];
double monto=(Double.parseDouble(datos[1].isEmpty()?"0":datos[1]))/100;
int tipoTransaccion=Integer.parseInt(datos[2].isEmpty()?"0":datos[2]);
String numeroSerieTPV=datos[3];
String usuario=datos[4];
String contrasena=datos[5];
String llave=datos[6];
String referencia=datos[7];
String referencia2=datos[8];
int plazo=Integer.parseInt(datos[9].isEmpty()?"0":datos[9]);
int cvv=Integer.parseInt(datos[10].isEmpty()?"0":datos[10]);
int cvv2=Integer.parseInt(datos[11].isEmpty()?"0":datos[11]);
int transaccionId=Integer.parseInt(datos[12].isEmpty()?"0":datos[12]);
int comercioId=Integer.parseInt(datos[13].isEmpty()?"0":datos[13]);
int terminalId=Integer.parseInt(datos[14].isEmpty()?"0":datos[14].trim());
StringBuffer buf = new StringBuffer();
buf.append("");
Transacciones transacciones=new Transacciones();
if(tipoTransaccion==1){
transacciones.compra(tarjeta, monto, comercioId, plazo, terminalId,llave);
}else if(tipoTransaccion==2){
transacciones.pago(tarjeta, monto, comercioId, terminalId,llave);
}else if(tipoTransaccion==3){
transacciones.disposicion(tarjeta, monto,comercioId, plazo, terminalId,llave);
}else if(tipoTransaccion==4){
transacciones.reporte(comercioId, terminalId,llave);
}else if(tipoTransaccion==5){
transacciones.validarUsuario(usuario, contrasena, numeroSerieTPV);
}else if(tipoTransaccion==6){
transacciones.confirmacion(transaccionId);
return;
}else{
transacciones.getEnvioDatos().setCodigoError("0");
transacciones.getEnvioDatos().setDescripcionError("Tipo de transaccion invalido.");
}
buf.append(transacciones.getEnvioDatos().getCodigoError()+"|"
+transacciones.getEnvioDatos().getDescripcionError()+"|"
+transacciones.getEnvioDatos().getFecha()+"|"
+transacciones.getEnvioDatos().getHora()+"|"
+transacciones.getEnvioDatos().getNombreCliente()+"|"
+transacciones.getEnvioDatos().getClave()+"|"
+transacciones.getEnvioDatos().getPromesas()+"|"
+transacciones.getEnvioDatos().getReporte()+"|"
+transacciones.getEnvioDatos().getLlave()+"|"
+transacciones.getEnvioDatos().getTerminalBloqueada()+"|"
+transacciones.getEnvioDatos().getTerminalEstatus()+"|"
+transacciones.getEnvioDatos().getTerminalId()+"|"
+transacciones.getEnvioDatos().getComercioId()+"|"
+transacciones.getEnvioDatos().getTerminalNombre()+"|"
+transacciones.getEnvioDatos().getSucursalId()+"|"
+transacciones.getEnvioDatos().getNombresucursal()+"|"
+transacciones.getEnvioDatos().getDireccionSucursal()+"|"
+transacciones.getEnvioDatos().getPermisoCompra()+"|"
+transacciones.getEnvioDatos().getPermisoDisposicion()+"|"
+transacciones.getEnvioDatos().getPermisoPago()+"|"
+transacciones.getEnvioDatos().getPermisoTiempoAire()+"|"
+transacciones.getEnvioDatos().getCompraMinima()+"|"
+transacciones.getEnvioDatos().getDisposicionMinima()+"|"
+transacciones.getEnvioDatos().getDisposicionMaxima()+"|"
+transacciones.getEnvioDatos().getPlazos()+"|");
if(buf.length()<SIZE) {
while(buf.length()<SIZE)
buf.append("*");
}
String str=buf.toString();
System.out.println(str);
String x=encriptacion("encrypt", str);
System.out.println("Just connected to " + s.getRemoteSocketAddress());
envio(x);
in.close();
} catch(SocketTimeoutException e) {
e.printStackTrace();
} catch(IOException e) {
e.printStackTrace();
}catch(Throwable e){
e.printStackTrace();
}finally{
}
}
public void envio(String x){
synchronized(lock){
DataOutputStream out=null;
try {
out = new DataOutputStream(s.getOutputStream());
out.write(x.getBytes(Charset.forName("UTF-8")), 0, x.length());
System.out.println(x);
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
But I still have issues when sending the response to the clients, the synchronized doesn't work, what am I doing wrong??
thanks again
Upvotes: 0
Views: 1827
Reputation: 28761
Summarizing comments:
There is no problem with multiple threads writing on different sockets concurrently. Besides, your synchronize(this)
has no effect -- there is a separate ServerThread object created for each connection (which is a good thing) so multiple threads have their own locks, effectively there will never be any wait for acquiring the lock. What is the exact problem you are facing? Try to put a breakpoint in the run method and step through it.
What is Encriptacion? Perhaps it is not thread-safe and requires synchronization? If the test a sending back simple string works, you can build on it slowly to get to where you want to be. You could for example, read all of input and respond with a string such as "Just connected to " + s.getRemoteSocketAddress()
which will help you verify that the multi-threading is working while also seeing different response from different concurrent connections.
From there, you could take small steps -- I would first add decrypting the request payload and writing it back in response (sort of echo server).
Upvotes: 1