Programmation Réseaux INF4032 - Bassem Haidar - PDF

Summary

Ce document présente une introduction aux réseaux informatiques, comprenant les concepts de base de la programmation réseau.

Full Transcript

INF4032 Réseaux Informatiques Bassem Haidar Programmation réseaux Chapter 03 PROGRAMMATION DES SOCKETS Objectif : apprendre à créer une application client/serveur qui communique à l'aide de sockets...

INF4032 Réseaux Informatiques Bassem Haidar Programmation réseaux Chapter 03 PROGRAMMATION DES SOCKETS Objectif : apprendre à créer une application client/serveur qui communique à l'aide de sockets socket  Socket API a host-local,  introduced in BSD4.1 UNIX, 1981 application-created, OS-controlled interface  explicitly created, used, released by apps (a “door”) into which  client/server paradigm application process can both send and  two types of transport service via socket API: receive messages  unreliable datagram to/from another  reliable, byte stream-oriented application process 3 PROGRAMMATION DE SOCKET AVEC TCP Socket: une porte entre le processus d'application et le protocole de transport final (UDP ou TCP) TCP service: transfert fiable d'octets d'un processus à un autre controlled by controlled by process application application process developer developer socket socket controlled by TCP with TCP with controlled by buffers, operating operating buffers, internet system system variables variables host or host or server server 4 PROGRAMMATION DE SOCKET EN TCP Le client doit contacter le serveur  Lorsqu'il est contacté par le client, le serveur  le processus serveur doit d'abord être en TCP crée un nouveau socket pour que le cours d'exécution processus serveur communique avec le  le serveur doit avoir créé un socket client (porte) qui accueille le contact du client  permet au serveur de parler avec Le client contacte le serveur par : plusieurs clients  création d'un socket TCP local client  numéros de port source utilisés pour distinguer les clients  spécifiant l'adresse IP, le numéro de port du processus serveur point de vue applicatif  Lorsque le client crée un socket : le client TCP fournit des informations fiables TCP établit la connexion au serveur TCP et en ordre transfert d'octets (« tuyau ») entre client et serveur 5 JARGON : « STREAM » (FLUX) Un stream (flux) est une suite de caractères qui sort/entre depuis/vers un processus. Un input stream (flux d'entrée) est attaché à une source d'entrée du processus (clavier ou socket). Un output stream (flux de sortie) est attaché à une source de sortie (moniteur ou socket). 6 PROGRAMMATION DE SOCKET EN TCP Exemple d'application client-serveur : 1) le client lit la ligne à partir de l'entrée standard (flux inFromUser), envoie au serveur via socket (flux outToServer) 2) le serveur lit la ligne du socket 3) le serveur convertit la ligne en majuscule, la renvoie au client 4) le client lit, imprime la ligne modifiée du socket (inFromServer stream) 7 INTERACTION SOCKET CLIENT/SERVEUR : TCP 8 SOCKETS APPLICATION ECHO  Dans cet exemple simple, le serveur acceptera les messages du client et gardera le compte de ces messages, faisant écho à chaque message (numéroté). Le protocole principal de ce service est que le client et le serveur doivent alterner entre l'envoi et la réception (le client initiant le processus avec son message d'ouverture, bien sûr).  Les seuls détails qui restent à déterminer sont les moyens d'indiquer quand le dialogue doit cesser et quelles données finales (le cas échéant) doivent être envoyées par le serveur. Pour cet exemple simple, la chaîne « ***CLOSE*** » sera envoyée par le client lorsqu'il souhaite fermer la connexion. Lorsque le serveur recevra ce message, il confirmera le nombre de messages précédents reçus puis fermera sa connexion avec ce client. Le client, bien sûr, doit attendre le message final du serveur avant de fermer la connexion de son côté. 10 APPLICATION ECHO: SERVEUR - STEP 1 1. Create a ServerSocket object.  Le constructeur ServerSocket requiert un numéro de port (1024–65535, pour les non réservés) comme argument. Par exemple : ServerSocket serverSocket = new ServerSocket(1234); 11 APPLICATION ECHO: SERVEUR - STEP 1  Constructors  ServerSocket(), puis bind(SocketAddress sockAddr) ou bind(SocketAddress sockAddr, int nbPendantes)  Rattachement local du socket TCP permettant éventuellement de fournir le nombre de connexions en attente (début de three way handshake, mais pas terminée, ou connexion pas encore prise en compte par l'application) 12 OTHER CONSTRUCTORS  ServerSocket(int port),  ServerSocket(int port, int nbPen)  ServerSocket(int port, int nbPen, InetAddress addr)  Observations on local attachment:  getInetAddress(),  getLocalPort() et  getLocalSocketAddress() 13 2. METTEZ LE SERVEUR EN ÉTAT D'ATTENTE. Socket s = serverSock.accept();  méthode de blocage, sauf si setSoTimeout () a été spécifié avec une valeur non nulle en millisecondes  L'objet Socket retourné est appelé "service socket" et représente la connexion établie (comme côté client)  Vous pouvez récupérer les adresses et les ports des deux côtés de la connexion avec cet objet socket de service.  Si plusieurs sockets sont renvoyés par la méthode accept() du même objet ServerSocket, ils sont attachés au même port et à la même adresse IP locale  => demultiplexing on (ipCli, portCli, ipSer, portSer) 14 15 3. CONFIGUREZ LES FLUX D'ENTRÉE ET DE SORTIE.  Les méthodes getInputStream et getOutputStream de la classe Socket sont utilisées pour obtenir des références aux flux associés au socket retourné à l'étape 2.  Ces flux seront utilisés pour la communication avec le client qui vient de se connecter. Pour une application sans interface graphique, nous pouvons envelopper un objet Scanner autour de l'objet InputStream renvoyé par la méthode getInputStream , afin d'obtenir une entrée orientée chaîne (comme nous le ferions avec l'entrée du flux d'entrée standard, System.in ).  Par exemple :  Scanner input = new Scanner(link.getInputStream());  De même, nous pouvons envelopper un objet PrintWriter autour de l'objet OutputStream renvoyé par la méthode getOutputStream. Fournir au constructeur PrintWriter un deuxième argument de true entraînera le vidage du tampon de sortie pour chaque appel de println (ce qui est généralement souhaitable). Par exemple :  PrintWriter output = new PrintWriter(link.getOutputStream(),true); 4. ENVOYER ET RECEVOIR DES DONNÉES.  Après avoir configuré nos objets Scanner et PrintWriter, l'envoi et la réception de données sont très simples. Nous utilisons simplement la méthode nextLine pour recevoir des données et la méthode println pour envoyer des données, tout comme nous pourrions le faire pour les E/S de la console. Par exemple : output.println("Awaiting data…"); String input = input.nextLine(); 5. STEP 5  Étant donné qu'une exception IOException peut être générée par n'importe laquelle des opérations de socket, un ou plusieurs blocs try doivent être utilisés. Plutôt que d'avoir un seul gros bloc try (sans variation dans le message d'erreur produit et, par conséquent, sans indication précise de l'opération qui a causé le problème), c'est probablement une bonne pratique d'avoir l'ouverture du port et le dialogue avec le client dans blocs d'essai séparés. Il est également recommandé de placer la fermeture de la socket dans une clause finally, de sorte que, qu'une exception se produise ou non, la socket sera fermée (à moins, bien sûr, que l'exception ne soit générée lors de la fermeture effective de la socket, mais il nous ne pouvons rien y faire)..  Puisque la clause finally aura besoin de connaître l'objet Socket, nous devrons déclarer cet objet dans une portée qui couvre à la fois le bloc try gérant le dialogue et le bloc finally. APPLCATION ECHO : CLIENT 19 1. ÉTABLIR UNE CONNEXION AU SERVEUR.  Nous créons un objet Socket, fournissant à son constructeur les deux arguments suivants :  l'adresse IP du serveur (de type InetAddress ) ;  le numéro de port approprié pour le service. (Le numéro de port des programmes serveur et client doit être le même, bien sûr !)  A local port is chosen to locally attach the socket  The three way handshake is negotiated with the server  Le socket représentant la connexion établie est renvoyé  Si un problème de connexion lève une IOException  Par souci de simplicité, nous placerons client et serveur sur le même hôte, ce qui nous permettra de récupérer l'adresse IP en appelant la méthode statique getLocalHost de la classe InetAddress. Par exemple : Socket link = new Socket(InetAddress.getLocalHost(),1234); 21 STEP 2 AND 3  2. Configurer les flux d'entrée et de sortie.  Ceux-ci sont configurés exactement de la même manière que les flux de serveur ont été configurés (en appelant les méthodes getInputStream et getOutputStream de l'objet Socket qui a été créé à l'étape 2).  3. Envoyer et recevoir des données.  L'objet Scanner côté client recevra les messages envoyés par l'objet PrintWriter côté serveur, tandis que l'objet PrintWriter côté client enverra les messages reçus par l'objet Scanner côté serveur (en utilisant respectivement les méthodes nextLine et println). AUTRES CONSTRUCTEURS  public Socket(String hote, int port) throws UnknownHostException, IOException  public Socket(InetAddress hote, int port) throws IOException  public Socket(String hote, int port, InetAddress adrLocale, int portLocal) throws IOException  public Socket(InetAddress hote, int port, InetAddress adrLocale, int portLocal) throws IOException 23 CLASSE SOCKET Information  public InetAddress getInetAddress()  public int getPort()  public int getLocalPort()  public InetAddress getLocalAddress() Data sending and receiving  public InputStream getInputStream() throws IOException  public OutputStream getOutputStream() throws IOException Closing  public void close() throws IOException 24 OBSERVATIONS ON CLIENT SOCKETS  IP address and port of local attachment getLocalAddress(), getLocalPort(), getLocalSocketAddress()  IP address and port to which the socket is connected getInetAddress(), getPort(), getRemoteSocketAddress()  Buffer size [set/get]SendBufferSize(), [set/get]ReceiveBufferSize()  Closing connection: close(), isClosed() closing one of the streams closes both directions of communication and the socket 25 SETSOTIMEOUT EXAMPLE EXAMPLE : LOWPORTSCANNER MULTITHREADED SERVER  La plupart des applications du monde réel doivent gérer plusieurs connexions en même temps  Implique un processus en deux étapes :  Les threads principaux allouent des threads individuels aux clients entrants  Ces threads gèrent toutes les interactions ultérieures entre le client et le serveur SOCKETS REVISITER LE SERVEUR D'ÉCHO TCP  Dans cet exemple simple, le serveur acceptera les messages du client et gardera le compte de ces messages, faisant écho à chaque message (numéroté). Le protocole principal de ce service est que le client et le serveur doivent alterner entre l'envoi et la réception (le client initiant le processus avec son message d'ouverture, bien sûr).  Les seuls détails qui restent à déterminer sont les moyens d'indiquer quand le dialogue doit cesser et quelles données finales (le cas échéant) doivent être envoyées par le serveur. Pour cet exemple simple, la chaîne « ***CLOSE*** » sera envoyée par le client lorsqu'il souhaite fermer la connexion. Lorsque le serveur recevra ce message, il confirmera le nombre de messages précédents reçus puis fermera sa connexion avec ce client. Le client, bien sûr, doit attendre le message final du serveur avant de fermer la connexion de son côté. 30 REVISITER LE SERVEUR D'ÉCHO TCP  Le serveur renvoie les messages à plusieurs clients  Utiliser une classe de support ClientHandler  A une référence au socket client concerné  Aux modifications apportées au TCPEchoClient  Peut contrôler les demandes de backlog (file d'attente de demandes !)  ServerSocket (port int, backlog int) UDP INTRODUCTION  Contrairement à TCP, nous verrons qu'avec UDP il y a 1. pas de poignée de main initiale entre les deux processus et donc pas besoin d'un socket accueillant 2. aucun flux n'est attaché aux sockets 3. les hôtes expéditeurs créent des paquets en attachant l'adresse de destination IP et le numéro de port à chaque lot d'octets qu'il envoie 4. le processus de réception doit démêler chaque paquet reçu pour obtenir les octets d'information du paquet INTRODUCTION - UDP create socket, create socket, serverSocket = port=x, for DatagramSocket() incoming request: serverSocket = DatagramSocket() Create address (hostid, port) Send Datagram read request from request using serverSocket clientSocket write reply to Read reply from serverSocket clientSocket specifying client host address, port umber Close clientSocket INTRODUCTION  Le package java.net contient deux classes pour vous aider à écrire des programmes Java qui utilisent des datagrammes pour envoyer et recevoir des paquets sur le réseau :  DatagramSocket,  DatagramPacket,  Un datagramme est un message indépendant et autonome envoyé sur le réseau dont l'arrivée, l'heure d'arrivée et le contenu ne sont pas garantis.  Les paquets de datagrammes sont utilisés pour mettre en œuvre un service de livraison de paquets sans connexion. Chaque message est acheminé d'une machine à une autre en fonction uniquement des informations contenues dans ce paquet. IMPLÉMENTATION D'UDP PAR JAVA  L'implémentation Java d'UDP est divisée en deux classes :  La classe DatagramPacket insère des octets de données dans des paquets UDP appelés datagrammes et vous permet de décompresser les datagrammes que vous recevez.  Un DatagramSocket envoie et reçoit des datagrammes UDP. Pour envoyer des données, vous placez les données dans un DatagramPacket et envoyez le paquet à l'aide d'un DatagramSocket.  Pour recevoir des données, vous prenez un objet DatagramPacket d'un DatagramSocket, puis inspectez le contenu du paquet. Les sockets eux-mêmes sont des créatures très simples. En UDP, tout ce qui concerne un datagramme, y compris l'adresse vers laquelle il est dirigé, est inclus dans le paquet lui-même ; le socket n'a besoin de connaître que le port local sur lequel écouter ou envoyer. DATAGRAMPACKET CLASS java.lang.Object  Used for both client and server | +--java.net.DatagramPacket  An independent message public final class DatagramPacket (datagram packet) is created extends Object using a DatagramPacket() constructor  4 constructors THE DATAGRAM CLASS - CONSTRUCTORS  DatagramPacket(byte[] buf, int length)  DatagramPacket for receiving packets of length length.  DatagramPacket(byte[] buf, int length, InetAddress address, int port)  Datagram packet for sending packets of length length to the specified port number on the specified host.  DatagramPacket(byte[] buf, int offset, int length)  DatagramPacket for receiving packets of length length, specifying an offset into the buffer  DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port)  Datagram packet for sending packets of length length with offset offset to the specified port number on the specified host. THE DATAGRAM CLASS - METHODS  InetAddress getAddress()  Returns the IP address of the machine to which this datagram is being sent or from which the datagram was received.  byte[] getData()  Returns the data received or the data to be sent.  int getLength()  Returns the length of the data to be sent or the length of the data received.  int getOffset()  Returns the offset of the data to be sent or the offset of the data received.  int getPort()  Returns the port number on the remote host to which this datagram is being sent or from which the datagram was received. THE DATAGRAM CLASS - METHODS  void setAddress(InetAddress iaddr)  changes the address a datagram packet is sent to  void setLength(int length)  Set the length for this packet.  void setPort(int port)  changes the port a datagram is addressed to THE DATAGRAM CLASS - METHODS  void setData(byte[] buf)  Set the data buffer for this packet.  void setData(byte[] buf, int offset, int length)  Set the data buffer for this packet. THE DATAGRAMSOCKET CLASS  La classe publique DatagramSocket (extend Object) implémente des sockets pour envoyer et recevoir des paquets de datagrammes  Les envois et les réceptions de diffusion UDP sont toujours activés sur un DatagramSocket  Le côté serveur écoute son DatagramSocket et envoie des données à un client chaque fois que le client le demande. Le côté client est un programme simple qui fait simplement une requête au serveur.  Trois constructeurs de datagrammes publics.  Notez que l'hôte (InetAddress ou String) et le port auquel vous souhaitez vous connecter sont spécifiés dans le DatagramPacket.  Deux des constructeurs spécifient également le port local à partir duquel les données seront envoyées (utile pour les hôtes avec plusieurs interfaces), et  On précise l'adresse locale. THE DATAGRAMSOCKET CLASS - CONSRUCTORS if the socket could not be  public DatagramSocket() throws SocketException opened, or the socket could bind to the specified local po  Datagram socket bound to any available port on the local host machine  public DatagramSocket(int port) throws SocketException  Datagram socket bound to the specified port on the local host machine  The local port must be between 0 and 65535 inclusive.  public DatagramSocket(int port, InetAddress laddr) throws SocketException  Datagram socket, bound to the specified local address. THE DATAGRAMSOCKET CLASS - METHODS  public void send(DatagramPacket p) throws IOException  Sends a datagram packet from this socket. The DatagramPacket includes information indicating the data to be sent, its length, the IP address of the remote host, and the port number on the remote host.  If there is a security manager, and the socket is not currently connected to a remote address, this method first performs some security checks. First, if p.getAddress().isMulticastAddress() is true, this method calls the security manager's checkMulticast method with p.getAddress() as its argument. If the evaluation of that expression is false, this method instead calls the security manager's checkConnect method with arguments p.getAddress().getHostAddress() and p.getPort(). Each call to a security manager method could result in a SecurityException if the operation is not allowed.  Throws : IOException - if an I/O error occurs; SecurityException - if a security manager exists and its checkMulticast or checkConnect method doesn't allow the send. THE DATAGRAM CLASS - METHODS  public void receive(DatagramPacket p) throws IOException  Receives a datagram packet from this socket. When this method returns, the DatagramPacket's buffer is filled with the data received. The datagram packet also contains the sender's IP address, and the port number on the sender's machine. This method blocks until a datagram is received. The length field of the datagram packet object contains the length of the received message. If the message is longer than the packet's length, the message is truncated. If there is a security manager, a packet cannot be received if the security manager's checkAccept method does not allow it.  Throws : IOException - if an I/O error occurs. THE SOCKET CLASS - METHODS  public InetAddress getLocalAddress()  Gets the local address to which the socket is bound. If there is a security manager, its checkConnect method is first called with the host address and -1 as its arguments to see if the operation is allowed.  Throws : SecurityException - if a security manager exists and its checkConnect method doesn't allow the operation.  public int getLocalPort()  Returns the port number on the local host to which this socket is bound.  public void close()  Closes this datagram socket. THE SOCKET CLASS - METHODS  public void connect(InetAddress address, int port)  Connects the socket to a remote address for this socket. When a socket is connected to a remote address, packets may only be sent to or received from that address. By default a datagram socket is not connected. A caller's permission to send and receive datagrams to a given host and port are checked at connect time.  When a socket is connected, receive and send will not perform any security checks on incoming and outgoing packets, other than matching the packet's and the socket's address and port. On a send operation, if the packet's address is set and the packet's address and the socket's address do not match, an IllegalArgumentException will be thrown. A socket connected to a multicast address may only be used to send packets.  Throws :  IllegalArgumentException - if the address is invalid or the port is out of range;  SecurityException - if the caller is not allowed to send datagrams to and receive datagrams from the address and port. THE SOCKET CLASS - METHODS  public void disconnect()  Disconnects the socket. This does nothing if the socket is not connected.  public InetAddress getInetAddress()  Returns the address to which this socket is connected. Returns null if the socket is not connected.  public int getPort()  Returns the port for this socket. Returns -1 if the socket is not connected.  public int getSoTimeout() throws SocketException  Retrive setting for SO_TIMEOUT. 0 returns implies that the option is disabled (i.e., timeout of infinity). THE SOCKET CLASS - METHODS  public void setSoTimeout(int timeout) throws SocketException  Enable/disable SO_TIMEOUT with the specified timeout, in milliseconds. With this option set to a non-zero timeout, a call to receive() for this DatagramSocket will block for only this amount of time. If the timeout expires, a java.io.InterruptedIOException is raised, though the ServerSocket is still valid. The option must be enabled prior to entering the blocking operation to have effect. The timeout must be > 0. A timeout of zero is interpreted as an infinite timeout  public void setSendBufferSize(int size) throws SocketException  Sets the SO_SNDBUF option to the specified value for this DatagramSocket. The SO_SNDBUF option is used by the platform's networking code as a hint for the size to use to allocate set the underlying network I/O buffers. Increasing buffer size can increase the performance of network I/O for high-volume connection, while decreasing it can help reduce the backlog of incoming data. For UDP, this sets the maximum size of a packet that may be sent on this socket. Because SO_SNDBUF is a hint, applications that want to verify what size the buffers were set to should call IllegalArgumentException - if the value is 0 or is negative THE SOCKET CLASS - METHODS  public void setReceiveBufferSize(int size) throws SocketException  Sets the SO_RCVBUF option to the specified value for this DatagramSocket. The SO_RCVBUF option is used by the platform's networking code as a hint for the size to use to allocate set the underlying network I/O buffers. Increasing buffer size can increase the performance of network I/O for high-volume connection, while decreasing it can help reduce the backlog of incoming data. For UDP, this sets the maximum size of a packet that may be sent on this socket. Since SO_RCVBUF is a hint, applications that want to verify what size the buffers were set to should call IllegalArgumentException - if the value is 0 or is negative.  public int getSendBufferSize() throws SocketException  Get value of the SO_SNDBUF option for this socket, that is the buffer size used by the platform for output on the this Socket.  public int getReceiveBufferSize() throws SocketException  Get value of the SO_RCVBUF option for this socket, that is the buffer size used by the platform for input on the this Socket. DAYTIME CLIENT DAYTIME SERVER UDPECHOCLIENT

Use Quizgecko on...
Browser
Browser