创建一个软件路由器
Creating a software router
我想构建一个软件路由器。
我已经编写了打开套接字、接收数据并打印其接收到的数据的代码。 GUI 将使用
Tk
下面是代码的一个简单版本,它基本上完成了我想做的事情,除了没有分叉 new_port 子例程。每次我单击提交按钮时,Tk window 都会卡住。如果有人可以协助添加一个分支到 new_port 子例程,以便它产生一个新的子进程。我的想法是我可以在表格中填写一个新端口并点击 sumbit。 window 关闭,然后我再次按新键放入一个新端口,现在第二个套接字与第一个套接字同时打开。 I.E端口1234和5678同时被监听
#!/usr/bin/perl -w
use IO::Socket::INET;
use Tk;
$myip = `ifconfig | grep -i inet | head -1 | cut -d ":" -f2 | cut -d " " -f1`;
sub new_port {
my $socket = new IO::Socket::INET (
LocalHost => "$myip",
LocalPort => "$myport",
Proto => 'tcp'
Reuse => 1);
die "Cannot create socket on local host" unless $socket;
print "Server waiting for client connection on port $myport\n";
while(1)
{
my $client_socket = $socket->accept();
my $client_address = $client_socket->peerhost();
my $client_port = $client_socket->peerport();
my $input_data = "";
my $received_data = "";
do
{
$client_socket->recv($received_data, 65536);
$input_data = $input_data . $received_data;
} while ($received_data ne "");
print "INPUT----------------------------------\n";
print "Data from $client_address on port $client_port\n";
print $input_data;
shutdown($client_socket, 1);
}
}
sub new_port_window {
my $sw = MainWindow->new;
$sw->geometry("200x100");
$sw->title("port opener");
$sw->Label(-text "Insert port #")->place(-anchor => 'center', -relx => 0.5, -rely => 0.2);
$sw->Entry(-bg => 'white', -fg => 'black', -textvariable => $myport)->place(-anchor => 'center', -relx => 0.5, -rely => 0.4);
$sw->Button(-text "submit", -command => sub{new_port})->place(width => 100,
-anchor => "center",
-relx => 0.5,
-rely => 0.8);
}
my $mw = MainWindow->new;
$mw->geometry("150x100");
$mw->title("GUI TEST NEW FUNCTION");
$mw->Label(-text => "click new")->place(-anchor => "center", -relx => 0.5, -rely => 0.3);
$mw->Button(-text => "NEW", -command =>sub{new_port_window})->place(-width => 50, -anchor => "center", -relx => 0.5, -rely => 0.8);
MainLoop;
所以我能够通过大量实验来实现这一点。诀窍是分叉子例程并将 pid 存储在一个文件中,以便稍后用于终止进程,该进程由于处于无限循环中而永远不会退出。
Sub forker {
$pid = fork ();
if ( $pid == 0 ) {
new_port();
}
my $pid_file = 'router.pid';
open (my $pidlog, '>>', $pid_file) or die "cannot open file";
print $pidlog "$pid\n";
close $pidlog;
}
我想构建一个软件路由器。
我已经编写了打开套接字、接收数据并打印其接收到的数据的代码。 GUI 将使用
Tk
下面是代码的一个简单版本,它基本上完成了我想做的事情,除了没有分叉 new_port 子例程。每次我单击提交按钮时,Tk window 都会卡住。如果有人可以协助添加一个分支到 new_port 子例程,以便它产生一个新的子进程。我的想法是我可以在表格中填写一个新端口并点击 sumbit。 window 关闭,然后我再次按新键放入一个新端口,现在第二个套接字与第一个套接字同时打开。 I.E端口1234和5678同时被监听
#!/usr/bin/perl -w
use IO::Socket::INET;
use Tk;
$myip = `ifconfig | grep -i inet | head -1 | cut -d ":" -f2 | cut -d " " -f1`;
sub new_port {
my $socket = new IO::Socket::INET (
LocalHost => "$myip",
LocalPort => "$myport",
Proto => 'tcp'
Reuse => 1);
die "Cannot create socket on local host" unless $socket;
print "Server waiting for client connection on port $myport\n";
while(1)
{
my $client_socket = $socket->accept();
my $client_address = $client_socket->peerhost();
my $client_port = $client_socket->peerport();
my $input_data = "";
my $received_data = "";
do
{
$client_socket->recv($received_data, 65536);
$input_data = $input_data . $received_data;
} while ($received_data ne "");
print "INPUT----------------------------------\n";
print "Data from $client_address on port $client_port\n";
print $input_data;
shutdown($client_socket, 1);
}
}
sub new_port_window {
my $sw = MainWindow->new;
$sw->geometry("200x100");
$sw->title("port opener");
$sw->Label(-text "Insert port #")->place(-anchor => 'center', -relx => 0.5, -rely => 0.2);
$sw->Entry(-bg => 'white', -fg => 'black', -textvariable => $myport)->place(-anchor => 'center', -relx => 0.5, -rely => 0.4);
$sw->Button(-text "submit", -command => sub{new_port})->place(width => 100,
-anchor => "center",
-relx => 0.5,
-rely => 0.8);
}
my $mw = MainWindow->new;
$mw->geometry("150x100");
$mw->title("GUI TEST NEW FUNCTION");
$mw->Label(-text => "click new")->place(-anchor => "center", -relx => 0.5, -rely => 0.3);
$mw->Button(-text => "NEW", -command =>sub{new_port_window})->place(-width => 50, -anchor => "center", -relx => 0.5, -rely => 0.8);
MainLoop;
所以我能够通过大量实验来实现这一点。诀窍是分叉子例程并将 pid 存储在一个文件中,以便稍后用于终止进程,该进程由于处于无限循环中而永远不会退出。
Sub forker {
$pid = fork ();
if ( $pid == 0 ) {
new_port();
}
my $pid_file = 'router.pid';
open (my $pidlog, '>>', $pid_file) or die "cannot open file";
print $pidlog "$pid\n";
close $pidlog;
}