Programmation des sockets Perl


Socket est également appelé « socket ». Les applications envoient généralement des requêtes au réseau ou répondent aux requêtes du réseau via « socket », afin que les hôtes ou les processus sur un ordinateur puissent communiquer.

Dans ce chapitre, nous allons vous apprendre à utiliser le service Socket en langage Perl.


Créer un serveur

  • Utilisez la fonction socket pour créer un service socket.

  • Utilisez la fonction bind pour lier le port.

  • Utilisez la fonction écouter pour écouter sur le port.

  • Utilisez la fonction accepter pour recevoir les demandes des clients.

Créer un client

  • Utilisez la fonction socket pour créer un service socket.

  • Utilisez la fonction connect pour vous connecter au serveur socket.

Le schéma suivant montre le processus de communication entre le client et le serveur :


Fonction de socket serveur

Fonction socket

En Perl, nous utilisons la fonction socket() pour créer une socket. Le format de syntaxe est le suivant :

socket( SOCKET, DOMAIN, TYPE, PROTOCOL );

Analyse des paramètres :

  • DOMAIN ​​​​​​spécifie le protocole défini pour le socket créé. Par exemple :


    • AF_INET représente le protocole réseau IPv4

    • AF_INET6 représente IPv6

    • AF_UNIX représente une socket locale (utilisant un fichier)

  • TYPE socket Le type peut être divisé en SOCK_STREAM ou SOCK_DGRAM selon qu'il est orienté connexion ou non-connexion

  • PROTOCOL devrait être (getprotobyname('tcp') )[2] . Spécifie le protocole de transport réel utilisé.

La fonction socket est donc appelée comme suit :

use Socket     # 定义了 PF_INET 和 SOCK_STREAM

socket(SOCKET,PF_INET,SOCK_STREAM,(getprotobyname('tcp'))[2]);

bind() La fonction

utilise bind() pour attribuer une adresse à la socket :

bind( SOCKET, ADDRESS );

SOCKET Un descripteur de socket. ADDRESS est l'adresse du socket (TCP/IP) contenant trois éléments :

  • Cluster d'adresses (TCP/IP, c'est AF_INET, il peut y en avoir 2 sur votre système)

  • Numéro de port (par exemple 21)

  • Adresse réseau (par exemple 10.12.12.168)

Créé à l'aide d'un socket () Une fois qu'un socket est créé, seul le protocole qu'il utilise est attribué et aucune adresse n'est attribuée. Avant d'accepter les connexions d'autres hôtes, bind() doit être appelé pour attribuer une adresse au socket.

Un exemple simple est le suivant :

use Socket        # 定义了 PF_INET 和 SOCK_STREAM

$port = 12345;    # 监听的端口
$server_ip_address = "10.12.12.168";
bind( SOCKET, pack_sockaddr_in($port, inet_aton($server_ip_address)))
   or die "无法绑定端口! \n";

or die Exécuté après échec de liaison de l'adresse.

Définissez un port pour une réutilisation immédiate en définissant l'option setsockopt() SO_REUSEADDR. La fonction

pack_sockaddr_in() convertit l'adresse au format binaire.

Fonction Listen()

Lorsque le socket est lié à une adresse, la fonction Listen() commencera à écouter d'éventuelles demandes de connexion. Cependant, cela ne peut être utilisé que lorsque un flux de données fiable est garanti :

listen( SOCKET, QUEUESIZE );

SOCKET : Un descripteur de socket.

QUEUESIZE : est un entier qui détermine la taille de la file d'attente d'écoute. Lorsqu'une demande de connexion arrive, elle entrera dans la file d'attente d'écoute ; lorsqu'une demande de connexion est acceptée par accept(), elle sera supprimée de la file d'attente ; file d'attente d'écoute ; lorsque la file d'attente est pleine, les nouvelles demandes de connexion renverront une erreur.

Une fois la connexion acceptée, renvoie 0 en cas de succès et -1 en cas d'erreur.

Fonction accept()

La fonction accept() accepte la connexion socket demandée. En cas de succès, renvoyez la forme compressée de l'adresse réseau, sinon renvoyez FALSE :

accept( NEW_SOCKET, SOCKET );

SOCKET : un descripteur de socket.

ADRESSE : ADDRESS est l'adresse du socket (TCP/IP) contenant trois éléments :

  • Cluster d'adresses (TCP/IP, c'est AF_INET, il est peut-être sur votre système Oui 2)

  • Numéro de port (par exemple 21)

  • Adresse réseau (par exemple 10.12.12.168)

accept() est généralement utilisé dans des boucles infinies :

while(1) {
   accept( NEW_SOCKET, SOCKT );
   .......
}

Les exemples ci-dessus peuvent surveiller les demandes des clients en temps réel.


Fonction client

connect() L'appel système de la fonction

connect() définit la connexion pour un socket. Les paramètres sont le descripteur de fichier et l'adresse de l'hôte.

connect( SOCKET, ADDRESS );

Ce qui suit crée une instance connectée au socket du serveur :

$port = 21;    #  ftp 端口
$server_ip_address = "10.12.12.168";
connect( SOCKET, pack_sockaddr_in($port, inet_aton($server_ip_address)))
    or die "无法绑定端口! \n";

Instance complète

Ensuite, nous utilisons un exemple complet pour comprendre toutes les fonctions du socket Application :

Serveur server.pl Code :

#!/usr/bin/perl -w
# Filename : server.pl

use strict;
use Socket;

# 使用端口 7890 作为默认值
my $port = shift || 7890;
my $proto = getprotobyname('tcp');
my $server = "localhost";  # 设置本地地址

# 创建 socket, 端口可重复使用,创建多个连接
socket(SOCKET, PF_INET, SOCK_STREAM, $proto)
   or die "无法打开 socket $!\n";
setsockopt(SOCKET, SOL_SOCKET, SO_REUSEADDR, 1)
   or die "无法设置 SO_REUSEADDR $!\n";

# 绑定端口并监听
bind( SOCKET, pack_sockaddr_in($port, inet_aton($server)))
   or die "无法绑定端口 $port! \n";

listen(SOCKET, 5) or die "listen: $!";
print "访问启动:$port\n";

# 接收请求
my $client_addr;
while ($client_addr = accept(NEW_SOCKET, SOCKET)) {
   # send them a message, close connection
   my $name = gethostbyaddr($client_addr, AF_INET );
   print NEW_SOCKET "我是来自服务端的信息";
   print "Connection recieved from $name\n";
   close NEW_SOCKET;
}

Ouvrez un terminal et exécutez le code suivant :

$ perl sever.pl
访问启动:7890

Client client.pl Code :

#!/usr/bin/perl -w
# Filename : client.pl

use strict;
use Socket;

# 初始化地址与端口
my $host = shift || 'localhost';
my $port = shift || 7890;
my $server = "localhost";  # 主机地址

# 创建 socket 并连接
socket(SOCKET,PF_INET,SOCK_STREAM,(getprotobyname('tcp'))[2])
   or die "无法创建 socket $!\n";
connect( SOCKET, pack_sockaddr_in($port, inet_aton($server)))
   or die "无法连接:port $port! \n";

my $line;
while ($line = <SOCKET>) {
        print "$line\n";
}
close SOCKET or die "close: $!";

Ouvrez un autre terminal et exécutez le code suivant :

$ perl client.pl
我是来自服务端的信息