Cómo solucionar el bloqueo del socket
Solución al bloqueo de la comunicación Socket
El proceso normal de la comunicación Socket:
El cliente envía un mensaje al servidor cuando el servidor recibe el. mensaje, se envía un mensaje de retroalimentación al cliente.
La implementación del código actual es:
Tanto el cliente como el servidor se bloquearon durante la lectura. Después de repetidas revisiones de información relevante y pruebas, se descubrió la causa raíz del problema.
El motivo del bloqueo de lectura es:
Cuando el cliente termina de enviar datos al servidor, el servidor está leyendo los datos, pero el servidor no tiene forma de juzgar cuándo lo hará automáticamente. interrumpir, por lo que el servidor se bloqueará en este lugar.
Después del bloqueo, el servidor no tiene forma de enviar datos al cliente. En este momento, los datos recibidos por el cliente también esperarán datos del servidor y se bloquearán aquí. En este momento, ni el servidor ni el cliente se cerrarán y seguirán bloqueados.
Cuando el cliente transfiere datos, el servidor no sabe cuándo terminará. No hay forma de determinarlo usando read!=-1, porque la secuencia del cliente no ha terminado y la secuencia siempre ha existido. , entonces el servidor piensa que la transferencia de datos no se ha completado.
Hay dos soluciones, las soluciones son las siguientes:
1. Una vez completada la transmisión del cliente, puede cerrar la transmisión usando socket.shutdownOutput() y socket.shutdownInput( ) Estos dos métodos cierran la transmisión y la otra parte puede recibir la señal final.
2. Las dos partes acordaron definir un terminador. Cada vez que el cliente envía un mensaje al servidor, agrega el terminador al final del envío; , si se lee el carácter final, prueba que terminó y el bucle ya no existe.
Código de servidor de opción 1:
[java] ver copia simple
paquete com.pactera.ok
importar java. .BufferedReader;
importar java.io.IOException;
importar java.io.InputStream
importar java.io.InputStreamReader
importar java.io.OutputStream;
importar java.io.PrintWriter;
importar java.net.ServerSocket
importar java.net. ;
/**
* @Título: TestZLFServer
* @Descripción:
* @empresa: XXXXXX
* @autor:XXXXXX-zhanglf
* @fecha:2017-5-16
* @versión:1.0.0
*/
clase pública TestZLFServer {
public static void main(String[] args) {
prueba {
ServerSocket ss=new ServerSocket ( 10086);
Socket s=ss.accept();
InputStream es=s.getInputStream()
BufferedReader br=nuevo BufferedReader(nuevo InputStreamReader) (es));
OutputStream os=s.getOutputStream();
PrintWriter pw=new PrintWriter(os);
//Leer usuario Ingrese información
String info=null;
while(((info=br.readLine()) !=null)){
System.out. "Soy el servidor, la información del usuario es: " info);
lt;span style="color: #ff0000;"gt;s.shutdownInput();lt;/spangt
}
//Dar una respuesta al cliente
String result="Cliente, he recibido el mensaje que enviaste y te informaré"
p; >pw.write(resultado);
pw.flush();
pw.close()
os.close();
br.close();
es.c
perder();
s.close();
ss.close();
} captura (IOException e) {
e.printStackTrace();
}
}
}
Código de cliente de opción 1:
[java] ver copia simple
paquete com.pactera.ok;
importar java.io.BufferedReader
importar java.io.IOException; p>
importar java.io.InputStream;
importar java.io.InputStreamReader
importar java.io.OutputStream; io.PrintWriter;
importar java.net.InetAddress;
importar java.net.Socket
importar java.net.UnknownHostException;
/**
* @Título: TestZLFClient
* @Descripción:
* @empresa: XXXXXX
* @ autor: XXXXXX-zhanglf
* @fecha: 2017-5-16
* @versión: 1.0.0
*/
clase pública TestZLFClient {
public static void main(String[] args) {
prueba {
Socket s =new Socket(InetAddress.getLocalHost() , 10086);
OutputStream os=s.getOutputStream();
PrintWriter pw=new PrintWriter(os);
InputStream es=s.getInputStream (
BufferedReader br=new BufferedReader(new InputStreamReader(is));
//Contenido SMS enviado al servidor
String info=" sssssssssss" ;
pw.write(info);
pw.flush();
lt; abarcar estilo="color: #ff0000;"gt ;s .shutdownOutput(); //Sin este código, el cliente no puede generar el resultado: lt;/spangt
//Recibir la respuesta del servidor
String re;
sult=null;
while(!((result=br.readLine())==null)){
System.out.println("Recibir información del servidor:" resultado
}
//Cerrar el recurso
br.close()
is.close(); p>
p>
pw.close();
os.close();
s.close(); captura (UnknownHostException e) {
e.printStackTrace();
} captura (IOException e) {
e.printStackTrace();
}
}
}
Código de servidor opción 2:
[java] ver copia simple
paquete com .pactera.ok3;
importar java.io.InputStream
importar java.io.OutputStream
importar java.net.ServerSocket; ;
importar java.net.Socket
/**
* @Título: Servidor3
* @Descripción: p>
* @empresa: XXXXX
* @autor: XXXXX-zhanglf
* @fecha: 2017-5-16
* @versión : 1.0.0
*/
servidor de clase pública3 {
public static void main(String[] args) {
intentar {
//Crea un ServerSocket del lado del servidor y escucha las solicitudes en el puerto especificado
ServerSocket ss = new ServerSocket(10086
System.out); .println("=== ==========El servidor espera el acceso del cliente==============="
//Escuche; a las solicitudes del cliente
Socket socket = ss.accept();
// Después de establecer una conexión con el cliente, lea la información enviada por el cliente
InputStream es = socket.getInputStream ();
byte[] buffer = nuevo byte[1024]
int len =
// Defina un generador de cadenas, utilícelo para almacenar datos enviados desde el cliente
StringBuilder sb = new StringBuilder()
int index;
;
mientras ( (len=is.read(buffer)) != -1 ) {
String temp = ""
String tmp = new; String(buffer, 0, 2);
/**01-Lógica de procesamiento separada agregada al sistema de crédito**/
if("xd".equals(tmp)) {
temp = new String(buffer, 0, len);
//System.out.println("temp ======: " temp ); p>
p>
// Cuando se lee el carácter final, salta del bucle
if ( (index=temp.indexOf("eof")) != -1 ) {
/ /Truncate la longitud especificada
sb.append(temp.substring(2, index));
break; >}
} else{
/**Lógica de procesamiento original de 02 núcleos**/
temp = new String(buffer, 0, len);
}
// Si el carácter final no se lee, continúe leyendo y agregue el generador de cadenas
sb.append(temp
);}
}
p>
System.out.println("Información del servidor del cliente: " sb.toString()); p>// Después de leer, envía los datos de respuesta al cliente
OutputStream out = socket.getOutputStream()
out.write("Hello Client!".getBytes(); );
out.write("eof".getBytes( )); // Escribe un terminador
out.flush(); ();
es.close();
es.close();
out.close(); ();
ss.close();
}catch (Excepción e) {
e.printStackTrace()
}
}
}
Código de cliente de opción 2:
[java] ver copia simple
paquete com.pactera.ok3;
importar java.io.InputStream;
importar java.io.OutputStream
importar java.net.InetAddress; p>
importar java.net.Socket;
/**
* @Título: Cliente3
* @Descripción:
* @empresa: XXXXX
* @autor: XXXXX-zhangl
f
* @date:2017-5-16
* @version:1.0.0
*/
clase pública Cliente3 {
public static void main(String[] args) {
try{
// Establecer una conexión con el servidor (número de host del servidor, Monitoreo del servidor número de puerto)
Socket socket = new Socket(InetAddress.getLocalHost(), 10086);
// Después de establecer una conexión con el servidor, puede escribir datos en el servidor
OutputStream out = socket.getOutputStream();
//Escribir datos en el servidor
out.write("xd|0|001101|150XXXXXXXX |Hola , ha retirado 200 yuanes de su número de tarjeta |".getBytes());
out.write("eof".getBytes()); // Escribe un terminador para indicar que la escritura es. completado
out.flush();
// Después de escribir, obtenga los datos de respuesta del servidor
InputStream es = socket.getInputStream(); /p>
byte[] buffer = new byte[1024];
int len = 0
//Defina un StringBuilder para almacenar los datos enviados por el cliente
StringBuilder sb = new StringBuilder();
int index
mientras ((len=is.read(buffer)) != -1 ) {
String temp = new String(buffer, 0, len);
// Cuando se lee el carácter final, salta del bucle
if ( (index=temp.indexOf("eof ")) != -1) {
sb.append(temp.substring(0, index));
break; /p>
}
sb.append(temp);
}
System.out.println("Información del cliente del servidor: " sb.toString());
out.close();
es.close();
socket.close();
}catch (Excepción e) {
e.printStackTrace()
}
}
}