Las aplicaciones de red se dividen en dos partes: cliente y servidor, y la clase Socket es una clase Java responsable de manejar la comunicación del cliente. A través de esta clase, puede conectarse a un servidor con una IP o nombre de dominio especificado, y puede enviar y recibir datos entre sí con el servidor. El uso de la clase de socket se discutirá en detalle en este artículo y varios artículos más tarde, incluidos los conceptos básicos de la clase de socket, varios métodos de conexión, los métodos get y establecidos, los tiempos de espera durante la conexión y las conexiones de red de cierre, etc.
En este artículo, discutiremos los pasos y métodos básicos para usar la clase Socket. En general, los programas de clientes de red deben realizar los siguientes tres pasos al conectarse a los programas de servicio.
1. Conéctese al servidor
El cliente puede conectarse al servidor de dos maneras, uno es conectarse al servidor a través de IP, y el otro es conectarse al servidor a través del nombre de dominio.
De hecho, estos dos métodos son esencialmente una forma. En el cliente subyacente, todos se conectan al servidor a través de IP, pero hay ciertas diferencias entre los dos métodos. Si el programa del servidor está conectado a través de IP, el cliente solo se conecta de acuerdo con IP. Si el servidor está conectado a través del nombre de dominio, el cliente debe resolver el nombre de dominio en IP a través de DNS y luego conectarse de acuerdo con esta IP.
En muchos lenguajes de programación o herramientas de desarrollo (como C/C ++, Delphi) al conectarse al servidor con el nombre de dominio, primero debe resolver el nombre de dominio a IP y luego conectarse a través de IP. En Java, la función de resolución de nombres de dominio se ha incluido en la clase Socket. Por lo tanto, solo necesitamos usar el nombre de dominio como usar IP.
El método más común para conectarse a los programas de servidor a través de la clase Socket es pasar el nombre IP o de dominio y el número de puerto como parámetros en la clase Socket a través del constructor de la clase Socket. Hay muchas formas sobrecargadas del constructor de la clase Socket. En esta sección, solo se discute uno de los formularios más utilizados: Socket Public (Host String Host, Int Port). Desde la definición de este constructor, solo necesita pasar la IP o el nombre de dominio y el número de puerto directamente al constructor. El siguiente código es un programa de ejemplo que se conecta a los programas del servidor:
paquete mysocket; import java.net.*; public class MyConnection {public static void main (string [] args) {try {if (args.length> 0) {socket socket = new Socket (args [0], 80); System.out.println (args [0] + "¡conectado con éxito!"); } else System.out.println ("¡Especifique IP o nombre de dominio!"); } Catch (Exception e) {System.err.println ("Mensaje de error:" + E.getMessage ()); }}} En lo anterior, el nombre IP o dominio se pasa al programa a través del parámetro de línea de comandos, y luego el puerto 80 de la IP o el nombre de dominio especificado a través del parámetro de línea de comando se conecta a través del socket de socket = nuevo socket (args [0], 80). Dado que el constructor de la clase Socket usa lanzamientos al definir, al llamar al constructor de la clase Socket, debe usar la instrucción Prueba ... Catch para captar el error o usar la instrucción Lanza para lanzar el error para la función principal.
Use la clase Socket para conectarse al servidor para determinar qué puertos se abren en un host. El siguiente código es un programa que escanea qué puertos se abren en esta máquina.
2. Enviar y recibir datos
Los dos métodos más importantes en la clase Socket son GetInputStream y GetOutputStream. Estos dos métodos se utilizan para obtener objetos InputStream y OutputStream para leer y escribir datos, respectivamente. InputStream aquí lee los datos enviados por el programa del servidor al cliente, y el OutputStream son los datos que el cliente desea enviar al programa del servidor.
Al escribir programas reales de clientes de red, si se utiliza GetInputStream o GetOutputStream, y a quién usar primero y quién usar más tarde está determinado por la aplicación específica. Por ejemplo, al conectarse al puerto 80 (generalmente el puerto predeterminado utilizado por el protocolo HTTP) del sitio web Post y Telecommunications Press (www.ptpress.com.cn), enviando una cadena y finalmente leyendo la información devuelta desde www.ptpress.com.cn.
paquete mysocket; import java.net.*; import java.io.*; public class MyConnection2 {public static void main (string [] args) lanza excepción {socket socket = new Socket ("www.ptpress.com.cn", 80); // Enviar datos al programa del servidor OutputStream OPS = Socket.getOutputStream (); OutputStreamWriter OPSW = new OutputStreamWriter (OPS); BufferedWriter BW = New BufferedWriter (OPSW); bw.write ("Hello World/R/N/R/N"); bw.flush (); // recibir datos del programa del servidor InputStream ips = Socket.getInputStream (); InputStreamReader iPSR = new InputStreamReader (IPS); BufferedReader BR = New BufferedReader (iPSR); Cadena S = ""; while ((s = br.readline ())! = null) system.out.println (s); socket.close (); }} Al escribir el código anterior, debe prestar atención a los siguientes dos puntos:
1. Para mejorar la eficiencia de la transmisión de datos, la clase Socket no transmite datos cada vez que se llama al método de escritura, pero escribe los datos para transferirse a un búfer (el valor predeterminado es 8192 bytes), y luego envía los datos en este búfer a través del método de descarga. Por lo tanto, bw.flush (); es necesario.
2. La razón por la cual "/r/n/r/n" se agrega después de Hello World al enviar una cadena se debe a que el encabezado del protocolo HTTP usa "/R/N/R/N" como el indicador final (el contenido detallado del protocolo HTTP se explicará más tarde). Por lo tanto, al agregar "/r/n/r/n" después de enviar una cadena, el programa del servidor puede pensar que el encabezado HTTP ha terminado y puede procesarse. Si no se agrega "/r/n/r/n", el programa del servidor esperará el final del encabezado HTTP, es decir, "/r/n/r/n". Si es así, el programa del servidor no enviará información de respuesta al cliente, y br.readline () se bloqueará porque no se puede leer para responder información hasta que la conexión se agotara.
3. Apague la conexión de red
Hasta ahora, tenemos una comprensión preliminar de los métodos de uso básicos de la clase Socket, pero después de que la clase Socket ha procesado los datos, el método final más razonable es usar el método de cierre de la clase Socket para cerrar la conexión de red. Aunque el método de cierre se ha utilizado en él, el método para cerrar la conexión de red no es solo el método de cierre. Veamos en qué circunstancias puede Java cerrar la conexión de red.
Hay cuatro situaciones en las que se pueden cerrar las conexiones de red:
Aunque todos estos 4 métodos pueden lograr el mismo objetivo, es mejor usar el primer o segundo método para cerrar la conexión de red. Esto se debe a que los métodos tercero y cuarto generalmente no cierran la conexión de red de inmediato. Si es así, para algunas aplicaciones, se dejará una gran cantidad de conexiones de red inútiles, lo que ocupará una gran cantidad de recursos del sistema.
Después de que se cierra el objeto de socket, podemos usar el método ampliado para determinar si un objeto de socket está en un estado cerrado. Sin embargo, lo que se devuelve mediante el uso del método IsClosed es el estado actual del objeto Socket. Es decir, independientemente de si el objeto Socket se ha conectado con éxito, ISClosde devuelve verdadero siempre que esté en el estado cerrado. Si solo crea un objeto de socket no conectado, IsClose también devuelve verdadero. Como se muestra en el siguiente código, False se emitirá.
Socket socket = new Socket (); System.out.println (Socket.isClosed ());
Además del método ISclose, la clase Socket también tiene un método con conexión para determinar si el objeto Socket está conectado con éxito. Cuando vea este nombre, los lectores pueden malinterpretarlo. De hecho, el método con conexión no determina el estado de conexión actual del objeto Socket, sino si el objeto Socket se ha conectado correctamente. Si se ha conectado con éxito, incluso si IsClose regresa verdadero ahora, ISConnected todavía devuelve verdadero. Por lo tanto, para determinar si el objeto de socket actual está en un estado conectado, los métodos ISclose e ISConectados deben usarse al mismo tiempo, es decir, el objeto Socket está en un estado conectado solo cuando IsClose devuelve falsos e INconnected Devuelve verdadero. El siguiente código demuestra el proceso de generación de varios estados del objeto Socket anterior.
paquete mysocket; import java.net.*; clase pública myCloseconnection {public static void printState (socket Socket, name de cadena) {System.out.println (name + ".IsClosed ():" + socket.isclosed ()); System.out.println (nombre + ".Isconnected ():" + Socket.isconnected ()); if (Socket.isClosed () == false && Socket.isConnected () == true) System.out.println (nombre + "en estado conectado!"); else System.out.println (nombre + "en estado no conectado!"); System.out.println (); } public static void main (string [] args) lanza la excepción {socket socket1 = null, socket2 = null; Socket1 = new Socket ("www.ptpress.com.cn", 80); printState (Socket1, "Socket1"); Socket1.getOutputStream (). Close (); printState (Socket1, "Socket1"); socket2 = new Socket (); printState (Socket2, "Socket2"); socket2.close (); printState (Socket2, "Socket2"); }} Después de ejecutar el código anterior, se mostrará la siguiente salida:
socket1.isClosed (): falso
socket1.isconnected (): verdadero
¡Socket1 está en un estado conectado!
socket1.isClosed (): verdadero
socket1.isconnected (): verdadero
¡Socket1 está en un estado no conectado!
socket2.isClosed (): falso
socket2.isconnected (): falso
¡Socket2 está en un estado no conectado!
socket2.isClosed (): verdadero
socket2.isconnected (): falso
¡Socket2 está en un estado no conectado!
A partir de los resultados de la salida, se puede ver que después de que la salida de Socket1 se cierra, Socket1 también se cierra automáticamente. En el código anterior, podemos ver que para un objeto Socket Socket2 que no está conectado al servidor, su método cerrado es falso. Si el método de Socket2 está cerrado devuelve verdadero, el método de cierre debe llamarse visualmente usando Socket2.close.
Aunque la mayoría de las veces, podemos usar la clase Socket o el método de cierre de la secuencia de entrada y salida para cerrar la conexión de red, a veces solo queremos cerrar el OutputStream o InputStream, y al cerrar la secuencia de entrada y salida, no cerramos la conexión de red. Esto requiere el uso de otros dos métodos de la clase de socket: shutdownInput y shutdownutput. Estos dos métodos solo cierran las transmisiones de entrada y salida correspondientes, pero no tienen la función de cerrar la conexión de red al mismo tiempo. Al igual que los métodos concluyados y están conectados, la clase Socket también proporciona dos métodos para determinar si las secuencias de entrada y salida del objeto Socket están cerrados. Estos dos métodos son ISINPUTSHUTDOWN () y isoutputShutdown (). El siguiente código demuestra el proceso de cierre solo de transmisión de entrada y salida:
paquete mysocket; import java.net.*; clase pública myCloseconnection1 {public static void printState (socket socket) {system.out.println ("isInputShutdown:" + Socket.isInputShutdown ()); System.out.println ("isoutputShutdown:" + Socket.isoutputShutdown ()); System.out.println ("IsClosed:" + Socket.isClosed ()); System.out.println (); } public static void main (string [] args) lanza excepción {socket socket = new Socket ("www.ptpress.com.cn", 80); printState (socket); socket.shutdownInput (); printState (socket); Socket.shutdownOutput (); printState (socket); }} Después de ejecutar la generación anterior, obtendrá la siguiente salida:
isinputshutdown: falso
isoutputshutdown: falso
ISCLOSED: FALSO
isinputshutdown: verdadero
isoutputshutdown: falso
ISCLOSED: FALSO
isinputshutdown: verdadero
isoutputshutdown: verdadero
ISCLOSED: FALSO
A partir de los resultados de la salida, podemos ver que el método cerrado siempre devuelve falso, por lo que es seguro que el cierre y el apagado no afectan el estado del objeto Socket.
Espero que este artículo te sea útil. Todo esto es para que Java use la clase Socket para recibir y enviar contenido de datos. ¡Espero que todos continúen siguiendo nuestro sitio web! Si desea aprender Java, puede continuar siguiendo este sitio web.