Pengaturcaraan soket Perl


Soket juga dipanggil "soket". Aplikasi biasanya menghantar permintaan ke rangkaian atau membalas permintaan rangkaian melalui "soket", supaya hos atau proses pada komputer boleh berkomunikasi.

Dalam bab ini kami akan mengajar anda cara menggunakan perkhidmatan Socket dalam bahasa Perl.


Buat pelayan

  • Gunakan fungsi soket untuk mencipta perkhidmatan soket.

  • Gunakan fungsi bind untuk mengikat port.

  • Gunakan fungsi dengar untuk mendengar pada port.

  • Gunakan fungsi terima untuk menerima permintaan pelanggan.

Buat klien

  • Gunakan fungsi soket untuk mencipta perkhidmatan soket.

  • Gunakan fungsi sambung untuk menyambung ke pelayan soket.

Rajah berikut menunjukkan proses komunikasi antara klien dan pelayan:


Fungsi soket pelayan

fungsi soket

Dalam Perl, kami menggunakan fungsi socket() untuk mencipta soket Format sintaks adalah seperti berikut:

socket( SOCKET, DOMAIN, TYPE, PROTOCOL );

Analisis parameter:

    <. 🎜 >
  • DOMAIN ​​​​menentukan set protokol untuk soket yang dibuat. Contohnya:


    • mewakili protokol rangkaian IPv4 AF_INET

    • mewakili IPv6 AF_INET6

    • mewakili soket setempat (menggunakan fail) AF_UNIX

  • TYPE soket Jenis boleh dibahagikan kepada SOCK_STREAM atau SOCK_DGRAM mengikut sama ada ia berorientasikan sambungan atau bukan sambungan

  • PROTOCOL hendaklah (getprotobyname('tcp') )[2] . Menentukan protokol pengangkutan sebenar yang digunakan.

Jadi fungsi soket dipanggil seperti berikut:

use Socket     # 定义了 PF_INET 和 SOCK_STREAM

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

bind() Fungsi

menggunakan bind() untuk memberikan alamat kepada soket :

bind( SOCKET, ADDRESS );

SOKET Deskriptor soket. ADDRESS ialah alamat soket (TCP/IP) yang mengandungi tiga elemen:

  • Alamat Kluster (TCP/IP, ia ialah AF_INET, ia mungkin 2 pada sistem anda)

  • Nombor port (contohnya 21)

  • Alamat rangkaian (contohnya 10.12.12.168)

Dibuat menggunakan soket () Selepas soket dicipta, hanya protokol yang digunakannya ditetapkan, dan tiada alamat diberikan. Sebelum menerima sambungan daripada hos lain, bind() mesti dipanggil untuk memberikan alamat kepada soket.

Contoh mudah adalah seperti berikut:

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";

atau mati Dilaksanakan selepas kegagalan untuk mengikat alamat.

Tetapkan port untuk penggunaan semula segera dengan menetapkan pilihan setsockopt() SO_REUSEADDR. Fungsi

pack_sockaddr_in() menukar alamat kepada format binari.

fungsi listen()

Apabila soket diikat pada alamat, fungsi listen() akan mula mendengar permintaan sambungan yang mungkin. Walau bagaimanapun, ini hanya boleh digunakan apabila aliran data yang boleh dipercayai dijamin:

listen( SOCKET, QUEUESIZE );

SOKET: Deskriptor soket.

QUEUESIZE: ialah integer yang menentukan saiz baris gilir mendengar Apabila permintaan sambungan tiba, ia akan memasuki baris gilir mendengar apabila permintaan sambungan diterima oleh accept(), ia akan dialih keluar daripada mendengar baris gilir; apabila baris gilir Selepas ia penuh, permintaan sambungan baharu akan mengembalikan ralat.

Setelah sambungan diterima, mengembalikan 0 untuk kejayaan dan -1 apabila ralat.

fungsi accept()

fungsi accept() menerima sambungan soket yang diminta. Jika berjaya, kembalikan bentuk mampat alamat rangkaian, jika tidak, kembalikan FALSE:

accept( NEW_SOCKET, SOCKET );

SOKET: deskriptor soket.

ALAMAT: ALAMAT ialah alamat soket (TCP/IP) yang mengandungi tiga elemen:

  • Kluster alamat (TCP/IP, ia adalah AF_INET, ia mungkin pada anda sistem Ya 2)

  • Nombor port (contohnya 21)

  • Alamat rangkaian (contohnya 10.12.12.168)

accept() biasanya digunakan dalam gelung tak terhingga:

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

Contoh di atas boleh memantau permintaan pelanggan dalam masa nyata.


Fungsi klien

connect() Fungsi

connect() system call menetapkan sambungan untuk soket Parameter ialah deskriptor fail dan alamat hos.

connect( SOCKET, ADDRESS );

Yang berikut mencipta tika yang disambungkan ke soket pelayan:

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

Contoh lengkap

Seterusnya kami menggunakan contoh lengkap untuk memahami semua fungsi soket Aplikasi:

Kod server.pl pelayan:

#!/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;
}

Buka terminal dan laksanakan kod berikut:

$ perl sever.pl
访问启动:7890

Kod client.pl pelanggan:

#!/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: $!";

Buka terminal lain dan laksanakan kod berikut:

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