关于 Perl 和 Perl 的问题Ruby 套接字编程
这里有四个代码:
代码 A:(Perl TCP 服务器)
prompt> perl -e '
use IO::Socket;
$s = IO::Socket::INET->new(LocalPort => 8080, Type => SOCK_STREAM, Reuse => 1, Listen => 10, Proto => "tcp") or die "$!";
while ($c = $s->accept) {
print while <$c>;
}'
代码 B:(Perl TCP 客户端)
prompt> perl -e '
use IO::Socket;
$c = IO::Socket::INET->new(PeerAddr => "localhost:8080") or die "$!";
while (<>) {
print $c $_
}'
代码 C:(Ruby TCP 服务器)
prompt> ruby -e '
require "socket"
s = TCPServer.new("localhost", 8080)
while( c = s.accept)
while l = c.gets
puts l
end
end'
代码 D:(Ruby TCP 客户端)
prompt> ruby -e '
require "socket"
c = TCPSocket.new("localhost", 8080)
while l = gets
c.puts l
end'
以下问题让我感到困惑:
代码 A 和代码B可以同时运行。我认为当后一个进程启动时它应该抛出一个“地址已被使用”错误,它与前一个进程绑定到相同的 TCP 端口。
两个(可能超过两个)代码 C 实例可以同时运行,而我无法运行两个代码 A 实例。
当代码 A 和代码 C 同时运行时,我通过 Google Chrome 访问了“http://localhost:8008”,然后代码 C 打印了 HTTP 消息,而代码 A 没有。
当我单独运行代码 C 时,代码 B 无法连接到它。
当我单独运行代码 A 时,代码 D 可以连接到它。
当代码A和代码C同时运行时,代码D连接到C,代码B连接A。
Here are four codes:
Code A: (Perl TCP Server)
prompt> perl -e '
use IO::Socket;
$s = IO::Socket::INET->new(LocalPort => 8080, Type => SOCK_STREAM, Reuse => 1, Listen => 10, Proto => "tcp") or die "$!";
while ($c = $s->accept) {
print while <$c>;
}'
Code B: (Perl TCP Client)
prompt> perl -e '
use IO::Socket;
$c = IO::Socket::INET->new(PeerAddr => "localhost:8080") or die "$!";
while (<>) {
print $c $_
}'
Code C: (Ruby TCP Server)
prompt> ruby -e '
require "socket"
s = TCPServer.new("localhost", 8080)
while( c = s.accept)
while l = c.gets
puts l
end
end'
Code D: (Ruby TCP Client)
prompt> ruby -e '
require "socket"
c = TCPSocket.new("localhost", 8080)
while l = gets
c.puts l
end'
The following issues confused me:
Code A and Code B can be run simultaneously. I thought it should threw an "Address already be used" Error when the latter process starts which bind to the same TCP port with former process.
Two (maybe more than two) instance of Code C can be run simulataneously, while I can't run two instance of Code A.
while Code A and Code C were being running simultaneously, I visited "http://localhost:8008" via Google Chrome, then Code C printed the HTTP messages, while Code A did not.
while I run Code C singlehandedly, Code B can not connect to it.
while I run Code A singlehandedly, Code D can connect to it.
while Code A and Code C were being running simultaneously, code D connected to C and Code B connected A.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在这种情况下,地址不会发生冲突,只会发生端口冲突。更具体地说,如果源端口相同。目标端口通常是相同的,因为这定义了服务可能存在的位置。
例如:http 服务器通常使用源端口 80 和“随机”目标端口。 http 客户端通常使用目标端口 80,源端口“随机”。 (不是真正随机的,但这超出了问题的范围。)
这个声明特别让我相信上面的代码实际上并没有被运行。具体来说这一行:
这可以解释您所描述的大多数问题。尝试将它们放入文件中并运行它们。从一次运行到下一次运行,您将减少拼写错误的可能性。
唯一剩下的未解决的问题是这个人:
。尝试运行 lsof -Pni:8080 (或您环境中类似的东西),以查看正在侦听的服务在那个端口上。
Ruby 脚本似乎存在双堆栈问题。它默认为 IPv6 本地主机,然后是 IPv6 本地站点,最后是 IPv4 本地主机。看起来好像是在内部指定源地址。
Perl 脚本运行正常。它可能会使用 in6addr_any 打开一个套接字并在 v4 和 v6 上舒适地监听。
The addresses wouldn't conflict in this situation, only ports. More specifically, if the source ports were the same. Destinations ports are regularly the same, as this defines where a service may exist.
Ex: http servers generally use source port 80 with destination ports "randomized". http clients generally use destination port 80 with source ports "randomized". (Not truly random, but that's beyond the scope of the question.)
This statement in particular leads me to believe the code above wasn't actually was was ran. Specifically this line:
This would explain most of the issues you're describing. Try putting each of these into files and running them. You'll lessen the possibility of typos from one run to the next.
The only remaining unsolved issue is this guy:
Try running lsof -Pni:8080 (or something similar in your environment), to see what services are listening on that port.
There appears to be a dual-stack issue with the Ruby script. It's defaulting to IPv6 localhost, then IPv6 site-local, and lastly IPv4 localhost. It's looks as if it's specifying the source address internally.
The Perl script is functioning correctly. It's likely opening a socket with in6addr_any and listening comfortably on v4 and v6.
服务器绑定127.0.0.1:8080,客户端绑定127.0.0.1:<某个空闲端口> (因为您没有请求将客户端绑定到特定端口)。 127.0.0.1:8080 != 127.0.0.1:<一些空闲端口>,所以没问题。
。您不能运行两个以上的“C”工作实例。两个套接字不可能绑定到相同的 IP 地址和端口。这就像试图给两个人相同的邮寄地址。
当然。因为“C”设法绑定到 127.0.0.1:8080,所以“A”无法绑定并死亡。
我不明白为什么。你得到什么错误?
The server is bound to 127.0.0.1:8080, and the client is bound to 127.0.0.1:<some free port> (since you didn't request to bind the client to a specific a port). 127.0.0.1:8080 != 127.0.0.1:<some free port>, so no problem.
You can't run more than two working instances of "C". It's impossible to have two sockets bound to the same IP address and port. It's like trying to give two people the same mailing address.
Of course. Because "C" manged to bind to 127.0.0.1:8080, "A" can't and dies.
I don't see why. What error do you get?
当我在一个文件中尝试对上面的代码进行一项修改时,
我收到以下错误..
拒绝了。在 pc.pl 第 4 行。”
所以我想知道发生了什么!所以我检查了另一个客户端程序,它仍然没有连接到 Ruby 客户端服务器。所以我想把重点放在 Ruby 服务器第一个
示例 Socket 上测试仪:
http://sourceforge.net/projects/sockettest/
Ruby 服务器:
Perl 客户端:(pc.pl )
其他代码供参考:
Perl 服务器:
Ruby 客户端:
FIX
我家里连接了 3 个系统,并将 localhost 替换为当前 PC 的实际 IP 解决了该问题。 (WINDOWS 中的 ipconfig 获取 IP)
Ruby 服务器:
Perl 客户端:
Thx Abraham
When I tried it in a file with one modification from above code
I got the below Error..
refused it. at pc.pl line 4."
So I was wondering what was going on!!! So I checked with a different client program and it was still not connecting to the Ruby client server. So I thought to focus on ruby server first
sample Socket Tester:
http://sourceforge.net/projects/sockettest/
Ruby Server:
Perl Client:(pc.pl)
The other code for reference:
Perl Server:
Ruby Client:
The FIX
I had 3 systems connected in my house and replacing localhost to the actual IP of the current PC resolved the issue. (ipconfig in WINDOWS to get the IP)
Ruby Server:
Perl Client:
Thx Abraham