分叉打开套接字对的子例程
Forking a subroutine that opens a socket pair
我想创建一个打开套接字的子程序。
我已经编写了打开套接字、接收数据并打印其接收到的数据的代码。 GUI是使用编写的
Tk
下面是代码,它基本上完成了我想做的事情,除了没有分叉 new_port
子例程。每次单击 submit
按钮时,Tk
window 都会卡住。我正在寻求有关将 fork
添加到 new_port
子例程的帮助,以便它生成一个新的子进程。我个人在执行 fork
时遇到语法错误或未将套接字推送到子进程的问题。
我的想法是我可以在表单中填写一个新端口并点击提交。 window 关闭,然后我再次按新键放入一个新端口,现在第二个套接字与第一个套接字同时打开。例如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;
自从我第一次尝试这个以来已经有很长时间了,所以我忘记了这是必须完成的方式还是只是众多可行方式中的一种,但要点是:
- 在分叉前创建套接字对
- 执行分叉
- 在 parent 中使用一个插座,在 child
中使用另一个插座
- 如果你希望套接字是单向的(来自parent
child 或 child 仅 parent),在 parent 和 child[=21= 中的适当套接字上调用
shutdown
]
由于您只想将数据从 parent 发送到 child,因此看起来像
($sock_child, $sock_par) = IO::Socket->socketpair(
Socket::AF_UNIX, Socket::SOCK_STREAM, Socket::PF_UNSPEC);
$pid = fork;
if ($pid) {
# parent
shutdown($sock_par, 0); # no more reading from parent
print $sock_par $data_to_pass_to_child;
...
} else {
# child
shutdown($sock_child, 1); # no more writing in child
$data_from_parent = <$sock_child>;
...
}
我想创建一个打开套接字的子程序。
我已经编写了打开套接字、接收数据并打印其接收到的数据的代码。 GUI是使用编写的
Tk
下面是代码,它基本上完成了我想做的事情,除了没有分叉 new_port
子例程。每次单击 submit
按钮时,Tk
window 都会卡住。我正在寻求有关将 fork
添加到 new_port
子例程的帮助,以便它生成一个新的子进程。我个人在执行 fork
时遇到语法错误或未将套接字推送到子进程的问题。
我的想法是我可以在表单中填写一个新端口并点击提交。 window 关闭,然后我再次按新键放入一个新端口,现在第二个套接字与第一个套接字同时打开。例如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;
自从我第一次尝试这个以来已经有很长时间了,所以我忘记了这是必须完成的方式还是只是众多可行方式中的一种,但要点是:
- 在分叉前创建套接字对
- 执行分叉
- 在 parent 中使用一个插座,在 child 中使用另一个插座
- 如果你希望套接字是单向的(来自parent
child 或 child 仅 parent),在 parent 和 child[=21= 中的适当套接字上调用
shutdown
]
由于您只想将数据从 parent 发送到 child,因此看起来像
($sock_child, $sock_par) = IO::Socket->socketpair(
Socket::AF_UNIX, Socket::SOCK_STREAM, Socket::PF_UNSPEC);
$pid = fork;
if ($pid) {
# parent
shutdown($sock_par, 0); # no more reading from parent
print $sock_par $data_to_pass_to_child;
...
} else {
# child
shutdown($sock_child, 1); # no more writing in child
$data_from_parent = <$sock_child>;
...
}