Red de conocimiento informático - Conocimiento informático - Cómo solucionar el bloqueo del socket

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:

* @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>

// 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()

}

}

}