Les applications réseau sont divisées en deux parties: le client et le serveur, et la classe de socket est une classe Java responsable de la gestion de la communication client. Grâce à cette classe, vous pouvez vous connecter à un serveur avec un nom de propriété intellectuel ou de domaine spécifié, et vous pouvez envoyer et recevoir des données les uns avec les autres avec le serveur. L'utilisation de la classe de socket sera discutée en détail dans cet article et plusieurs articles plus tard, y compris les bases de la classe de socket, diverses méthodes de connexion, les méthodes GET et définissent, les délais d'attente pendant la connexion et la fermeture des connexions du réseau, etc.
Dans cet article, nous discuterons des étapes de base et des méthodes d'utilisation de la classe de socket. Généralement, les programmes clients réseau doivent effectuer les trois étapes suivantes lors de la connexion aux programmes de service.
1. Connectez-vous au serveur
Le client peut se connecter au serveur de deux manières, l'une consiste à se connecter au serveur via IP, et l'autre est de se connecter au serveur via le nom de domaine.
En fait, ces deux méthodes sont essentiellement uniques. Chez le client sous-jacent, ils se connectent tous au serveur via IP, mais il existe certaines différences entre les deux méthodes. Si le programme serveur est connecté via IP, le client se connecte uniquement en fonction de l'IP. Si le serveur est connecté via le nom de domaine, le client doit résoudre le nom de domaine en IP via DNS, puis se connecter en fonction de cette IP.
Dans de nombreux langages de programmation ou outils de développement (tels que C / C ++, Delphi) Lorsque vous vous connectez au serveur à l'aide du nom de domaine, vous devez d'abord résoudre le nom de domaine en IP, puis vous connecter via IP. En Java, la fonction de résolution de noms de domaine a été incluse dans la classe de socket. Par conséquent, nous n'avons qu'à utiliser le nom de domaine comme l'utilisation d'IP.
La méthode la plus courante de connexion aux programmes de serveurs via la classe de socket est de passer le nom IP ou le nom de domaine et le numéro de port en tant que paramètres dans la classe de socket via le constructeur de la classe de socket. Il existe de nombreuses formes surchargées du constructeur de la classe de socket. Dans cette section, une seule des formulaires les plus couramment utilisées est discutée: Public Socket (String Host, int port). D'après la définition de ce constructeur, il vous suffit de passer directement le nom IP ou le nom de domaine et le numéro de port dans le constructeur. Le code suivant est un exemple de programme qui se connecte aux programmes de serveur:
Package MySocket; importer java.net. *; classe publique MyConnection {public static void main (String [] args) {try {if (args.length> 0) {socket socket = new socket (args [0], 80); System.out.println (args [0] + "connecté avec succès!"); } else System.out.println ("Veuillez spécifier IP ou nom de domaine!"); } catch (exception e) {System.err.println ("Message d'erreur:" + e.getMessage ()); }}} Dans ce qui précède, l'IP ou le nom de domaine est transmis dans le programme via le paramètre de ligne de commande, puis le port 80 de l'IP ou le nom de domaine spécifié via le paramètre de ligne de commande est connecté via le socket socket = new socket (args [0], 80). Étant donné que le constructeur de classe de socket utilise des lancers lors de la définition, lors de l'appel du constructeur de classe de socket, vous devez utiliser l'instruction Try ... Catch pour attraper l'erreur, ou utiliser l'instruction LORDS pour lancer l'erreur de la fonction principale.
Utilisez la classe Socket pour vous connecter au serveur pour déterminer quels ports sont ouverts sur un hôte. Le code suivant est un programme qui scanne les ports ouverts dans cette machine.
2. Envoyer et recevoir des données
Les deux méthodes les plus importantes de la classe Socket sont GetInputStream et GetOutputStream. Ces deux méthodes sont utilisées pour obtenir des objets InputStream et OutputStream pour la lecture et l'écriture de données, respectivement. L'inputStream lit ici les données envoyées par le programme serveur au client, et le sortie de sortie est les données que le client souhaite envoyer au programme du serveur.
Lors de la rédaction de programmes clients réseau réels, il faut utiliser GetInputStream ou GetOutputStream, et qui utiliser d'abord et qui utiliser plus tard est déterminé par l'application spécifique. Par exemple, en se connectant au port 80 (généralement le port par défaut utilisé par le protocole HTTP) du site Web de la publication et des télécommunications appuyez sur (www.ptpress.com.cn), en envoyant une chaîne, et enfin en lisant les informations renvoyées sur www.ptpress.com.cn.
package mysocket; import java.net. *; import java.io. *; classe publique MyConnection2 {public static void main (String [] args) lève une exception {socket socket = new socket ("www.ptpress.com.cn", 80); // Envoi des données au programme Server OutputStream Ops = socket.getOutputStream (); OutputStreamWriter OPSW = new OutputStreamWriter (OPS); BufferedWriter bw = new BufferedWriter (OPSW); BW.Write ("Hello World / R / N / R / N"); bw.flush (); // reçoit des données du programme Server InputStream ips = socket.getInputStream (); InputStreamReader iPSR = new inputStreamReader (ips); BufferedReader br = new BufferedReader (IPSR); String s = ""; while ((s = br.readline ())! = null) System.out.println (s); socket.close (); }} Lorsque vous écrivez le code ci-dessus, vous devez faire attention aux deux points suivants:
1. Afin d'améliorer l'efficacité de la transmission des données, la classe de socket ne transmet pas les données à chaque fois que la méthode d'écriture est appelée, mais écrit les données à transférer dans un tampon (la valeur par défaut est 8192 octets), puis envoie les données de ce tampon par le biais de la méthode Flush. Par conséquent, bw.flush (); est nécessaire.
2. La raison pour laquelle "/ r / n / r / n" est ajouté après Hello World lors de l'envoi d'une chaîne est parce que l'en-tête du protocole HTTP utilise "/ r / n / r / n" comme indicateur de fin (le contenu détaillé du protocole HTTP sera expliqué plus tard). Par conséquent, en ajoutant "/ r / n / r / n" après avoir envoyé une chaîne, le programme serveur peut penser que l'en-tête HTTP est terminé et peut être traité. Si "/ r / n / r / n" n'est pas ajouté, le programme serveur attendra la fin de l'en-tête HTTP, c'est-à-dire "/ r / n / r / n". Si c'est le cas, le programme Server n'enverra pas d'informations de réponse au client, et br.readline () sera bloqué car il ne peut pas être lu pour répondre aux informations tant que la connexion a expiré.
3. Éteignez la connexion réseau
Jusqu'à présent, nous avons une compréhension préliminaire des méthodes d'utilisation de base de la classe de socket, mais après que la classe de socket a traité les données, la méthode de fin la plus raisonnable consiste à utiliser la méthode proche de la classe de socket pour fermer la connexion réseau. Bien que la méthode de clôture ait été utilisée, la méthode de fermeture de la connexion réseau n'est pas seulement la méthode de fermeture. Voyons dans quelles circonstances Java peut arrêter la connexion réseau.
Il y a quatre situations où les connexions réseau peuvent être fermées:
Bien que toutes ces 4 méthodes puissent atteindre le même objectif, il est préférable d'utiliser la première ou la deuxième méthode pour fermer la connexion réseau. En effet, les troisième et quatrième méthodes ne ferment généralement pas la connexion réseau immédiatement. Si c'est le cas, pour certaines applications, un grand nombre de connexions de réseau inutiles seront laissées, qui occuperont une grande quantité de ressources système.
Une fois l'objet de socket fermé, nous pouvons utiliser la méthode ISCOSOSE pour déterminer si un objet de douille est à l'état fermé. Cependant, ce qui est renvoyé en utilisant la méthode iscosée est l'état actuel de l'objet de socket. Autrement dit, que l'objet de socket ait été connecté avec succès, Isclosde renvoie vrai tant qu'il est à l'état fermé. Si vous créez simplement un objet de socket non connecté, IsClose renvoie également True. Comme indiqué dans le code suivant, False sera sorti.
Socket socket = new socket (); System.out.println (socket.isclosed ());
En plus de la méthode ISClose, la classe de socket a également une méthode ISConned pour déterminer si l'objet de socket est connecté avec succès. Lorsque vous voyez ce nom, les lecteurs peuvent le comprendre. En fait, la méthode ISConned détermine non pas l'état de connexion actuel de l'objet de socket, mais si l'objet de socket a été connecté avec succès. S'il a été connecté avec succès, même si ISCLOSE renvoie true maintenant, Isconned Renvoie toujours True. Par conséquent, pour déterminer si l'objet de socket actuel est à l'état connecté, les méthodes ISCLOSE et ISConned doivent être utilisées en même temps, c'est-à-dire que l'objet de socket est dans un état connecté uniquement lorsque Isclose Renvoie False et Isconned Renvoie True. Le code suivant démontre le processus de génération de divers états de l'objet de socket ci-dessus.
package mysocket; import java.net. *; classe publique MyCloseConnection {public static void printstate (socket socket, string name) {System.out.println (name + ".isclosed ():" + socket.isclosed ()); System.out.println (nom + ".isconnected ():" + socket.isconnected ()); if (socket.isclosed () == false && socket.isconnected () == true) System.out.println (name + "dans l'état connecté!"); else System.out.println (nom + "à l'état non connecté!"); System.out.println (); } public static void main (String [] args) lève une exception {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"); }} Après avoir exécuté le code ci-dessus, la sortie suivante sera affichée:
socket1.isclosed (): false
socket1.isconnected (): true
Socket1 est dans un état connecté!
socket1.isclosed (): true
socket1.isconnected (): true
Socket1 est dans un état non connecté!
socket2.isclosed (): faux
socket2.isconnected (): faux
Socket2 est dans un état non connecté!
socket2.isclosed (): true
socket2.isconnected (): faux
Socket2 est dans un état non connecté!
D'après les résultats de sortie, on peut voir qu'après la fermeture de la sortie de Socket1, Socket1 est également fermé automatiquement. Dans le code ci-dessus, nous pouvons voir que pour un socket socket2 qui n'est pas connecté au serveur, sa méthode iscosée est fausse. Si la méthode Socket2 isClosed Renvoie True, la méthode Close doit être appelée affichage à l'aide de socket2.close.
Bien que la plupart du temps, nous puissions utiliser la classe de socket ou la méthode de fermeture du flux d'entrée et de sortie pour fermer la connexion réseau, nous voulons parfois fermer le Sortiestream ou InputStream, et tout en fermant le flux d'entrée et de sortie, nous ne fermons pas la connexion réseau. Cela nécessite l'utilisation de deux autres méthodes de la classe de socket: ShutdownInput et ShutdownOutput. Ces deux méthodes ne ferment que les flux d'entrée et de sortie correspondants, mais ils n'ont pas la fonction de fermer la connexion réseau en même temps. Comme les méthodes iscosées et isConnectées, la classe de socket fournit également deux méthodes pour déterminer si les flux d'entrée et de sortie de l'objet de socket sont fermés. Ces deux méthodes sont IsInputshutdown () et IsOutSputshutdown (). Le code suivant montre le processus de fermeture uniquement des flux d'entrée et de sortie:
package mysocket; import java.net. *; classe publique mycloseconnection1 {public static void printstate (socket socket) {System.out.println ("isInputshutdown:" + socket.isinputshutdown ()); System.out.println ("IsOutStHutdown:" + socket.isOutStHutdown ()); System.out.println ("isClosed:" + socket.isclosed ()); System.out.println (); } public static void main (String [] args) lève une exception {socket socket = new socket ("www.ptpress.com.cn", 80); Printstate (socket); socket.shutdownInput (); Printstate (socket); socket.shutdownoutput (); Printstate (socket); }} Après avoir exécuté la génération ci-dessus, vous obtiendrez la sortie suivante:
isInputshutdown: faux
isOutputshutdown: faux
isClosed: faux
isInputshutdown: vrai
isOutputshutdown: faux
isClosed: faux
isInputshutdown: vrai
IsOutputshutdown: vrai
isClosed: faux
D'après les résultats de sortie, nous pouvons voir que la méthode iscosée renvoie toujours FALSE, il est donc certain que Shutdownutput et ShutdownOutput n'affectent pas l'état de l'objet Socket.
J'espère que cet article vous sera utile. C'est tout pour Java d'utiliser la classe Socket pour recevoir et envoyer du contenu de données. J'espère que tout le monde continuera à suivre notre site Web! Si vous souhaitez apprendre Java, vous pouvez continuer à suivre ce site Web.