當前位置:首頁 » Perl » Perl Socket編程

Perl Socket編程

Perl Socket編程教學,例子教學,參考手冊和代碼 -

注: 如果你是知道Unix套接字,然後你可以跳過介紹部分。

什麼是socket?

另一個位計算機專業術語? 讓我們看看網絡的曆史,這是一個伯克利分校UNIX的進程之間建立一個虛擬的全雙工連接的機製。這後來被移植到所有已知的操作係統能夠跨越地域位置上運行不同的操作係統,軟件係統之間的通信。如果冇有套接字,大多數的網絡係統之間的通信將永遠也不會發生的。

在仔細看看; 一個典型的計算機係統的網絡上的接收和發送信息,運行在它之上的各種應用程序所必須的。 此信息被發送到係統中,由於一個唯一的IP地址被指定給它。在係統上,此信息提供給相關的應用程序在不同的端口上偵聽。例如,一個網絡瀏覽器監聽80端口的信息。 同時,我們也可以編寫應用程序在一個特定的端口號,收聽和發送信息。

現在,讓我們總結一下,一個套接字是IP地址和端口,它們可以連接。

為了說明的套接字,我們將使用客戶端 - 服務器端編程的一個例子。為了完成一個客戶端服務器架構,我們就得通過以下步驟

創建一個服務器

  • 創建一個socket套接字調用。
  • 將套接字綁定到一個端口地址綁定調用。
  • 調用同監聽,監聽套接字上的端口地址。
  • 接受客戶端連接和接受調用。

創建一個客戶端

  • 創建一個socket套接字調用。
  • 連接(套接字)連接調用到遠程機器。



創建一個套接字

建立網絡連接的第一個步驟是創建一個套接字,使用Socket()函數

socket( SOCKET, DOMAIN, TYPE, PROTOCOL ); creates a socket 

套接字創建了一個SOCKET, 其他三個參數都是整數,它應該有以下值的TCP/IP連接。

  • DOMAIN 應該是PF_INET。這可能在您的電腦上。
  • TYPE 應該是SOCK_STREAM的TCP/IP連接。
  • PROTOCOL 應該是(getprotobyname('tcp'))[2]。它是套接字的特定的協議(如TCP)。

因此,調用socket函數將是這樣的:

  use Socket     #defines PF_INET and SOCK_STREAM
  socket(SOCKET,PF_INET,SOCK_STREAM,(getprotobyname('tcp'))[2]);


綁定到套接字地址

創建的套接字的套接字是最新的,他們還冇有被使用的計算機主機名或端口號。 下一個socket()函數bind()的補充了這些套接字他們將接受來自客戶端連接到指定端口,服務器使用bind()函數。
 bind( SOCKET, ADDRESS ) binds a network ADDRESS to a SOCKET.

ADDRESS 是一個套接字地址(TCP/ IP)數據包包含三個元素的字符串

  1. 地址族(對於TCP / IP,這是AF_INET,可能在您的係統上)
  2. 端口號(例如21)
  3. 互聯網的計算機地址(例如10.12.12.168)

正如bind()服務器使用,並不需要知道它自己的地址,因此參數列表看起來像這樣:

$port = 12345;    # the port 
   bind( SOCKET, pack( 'Sn4x8', AF_INET, $port, "\0\0\0\0" ))
       or die "Can't bind to port $port! \n";


or die 子句是非常重要的 -如果一台服務器死了,冇有未完成的連接的端口不會立即可重複使用的,除非你使用這個選項SO_REUSEADDR使用setsockopt()函數。 這裡pack()函數被用來打包所有數據成二進製格式。


監聽端口

如果這是一個服務器程序,那麼它需要調用listen()監聽在指定的端口。

listen( SOCKET, QUEUESIZE );

上麵的調用是必須對所有服務器以及這裡QUEUESIZE是連接請求允許的最大數量。一般情況下,listen()是用來在一個無限循環。隻要一個連接到服務器處理並然後,立即去回到監聽更多的連接。


接收連接

如果這是一個服務器程序,那麼它需要發出調用access()函數來接受傳入的連接。

accept( NEW_SOCKET, SOCKET );

調用accept接收socket()函數返回的套接字描述符。成功完成此調用後,將返回一個新的socket描述符。今後所有客戶端和服務器之間的通信發生的NEW_SOCKET和SOCKET是返回自己最擅長的 : listen()的一個新的連接。access() 調用失敗,則返回FLASE我們最初使用的Socket模塊中所定義的。

你會經常看到的accept()用於在一個while循環,如下所示

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


現在,所有與服務器的調用,讓我們看到的調用將被客戶端要求.


連接的建立

如果你要準備客戶端程序,然後使用socket()調用後,你將不得不使用另一個調用connect()連接到服務器。

 connect( SOCKET, ADDRESS );
這裡的地址是類似bind調用的遠程服務器的IP地址,但它包含一個套接字地址。
   $port = 21;    # the  ftp port
   $server_ip_address = "10.12.12.168";
   connect( SOCKET, pack( 'Sn4x8', AF_INET, $port, $server ))
       or die "Can't connect to port $port! \n";

如果你連接到服務器成功後,你就可以開始你的命令發送到服務器使用SOCKET 描述符。

現在讓我們把所有的東西放在一起


創建服務器腳本

#!/usr/bin/perl -w
# server.pl by www.gitbook.net
#--------------------

use strict;
use Socket;

# use port 7890 as default
my $port = shift || 7890;
my $proto = getprotobyname('tcp');

# create a socket, make it reusable
socket(SOCKET, PF_INET, SOCK_STREAM, $proto) 
   or die "Can't open socket $!\n";
setsockopt(SOCKET, SOL_SOCKET, SO_REUSEADDR, 1) 
   or die "Can't set socket option to SO_REUSEADDR $!\n";

# bind to a port, then listen
bind( SOCKET, pack( 'Sn4x8', AF_INET, $port, "\0\0\0\0" ))
       or die "Can't bind to port $port! \n";
listen(SOCKET, 5) or die "listen: $!";
print "SERVER started on port $port\n";

# accepting a connection
my $client_addr;
while ($client_addr = accept(NET_SOCKET, SOCKET)) {
	# send them a message, close connection
	print NEW_SOCKET "Smile from the server";
	close NEW_SOCKET;
}

現在啟動以上服務器

要運行該服務器在後台模式下發出Unix提示符下麵的命令

$sever.pl&



客戶端創建的腳本

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

use strict;
use Socket;

# initialize host and port
my $host = shift || 'localhost';
my $port = shift || 7890;
my $server = "10.12.12.168";
# by www.gitbook.net
# create the socket, connect to the port
socket(SOCKET,PF_INET,SOCK_STREAM,(getprotobyname('tcp'))[2])
   or die "Can't create a socket $!\n";
connect( SOCKET, pack( 'Sn4x8', AF_INET, $port, $server ))
       or die "Can't connect to port $port! \n";

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