以下是四个代码:
代码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同时运行时,我通过谷歌浏览器访问了“http:// localhost:8008”,然后代码C打印了HTTP消息,而代码A则没有。
当我单独运行Code C时,代码B无法连接到它。
当我单独运行代码A时,代码D可以连接到它。
当代码A和代码C同时运行时,代码D连接到C,代码B连接A.
答案 0 :(得分:1)
代码A和代码B可以同时运行。我认为它应该抛出一个“地址已经被使用”错误,当后一个进程开始时,它与前一个进程绑定到同一个TCP端口。
在这种情况下,地址不会发生冲突,只有端口。更具体地说,如果源端口是相同的。目标端口通常是相同的,因为它定义了服务可能存在的位置。
Ex:http服务器通常使用源端口80,目标端口为“randomized”。 http客户端通常使用目标端口80,源端口“随机化”。 (不是真正的随机,但这超出了问题的范围。)
当代码A和代码C同时运行时,我通过谷歌浏览器访问了“http:// localhost:8008”,然后代码C打印了HTTP消息,而代码A则没有。
这句话特别让我相信上面的代码实际上并没有被运行。特别是这一行:
s = TCPServer.new(“localhost”,8080)
这可以解释您所描述的大部分问题。尝试将每个文件放入文件并运行它们。你将减少从一次运行到另一次运行的拼写错误的可能性。
唯一尚未解决的问题是这个人:
代码C的两个(可能多于两个)实例可以同时运行,而我无法运行代码A的两个实例。
尝试运行lsof -Pni:8080(或您环境中的类似内容),以查看正在该端口上侦听的服务。
Ruby脚本似乎存在双栈问题。它默认为IPv6 localhost,然后是IPv6 site-local,最后是IPv4 localhost。它看起来好像是在内部指定源地址。
Perl脚本运行正常。它很可能用in6addr_any打开一个套接字并在v4和v6上轻松收听。
答案 1 :(得分:1)
代码A和代码B可以同时运行。我认为它应该抛出一个“地址已被使用”错误,当后一个进程开始绑定到与前一个进程相同的TCP端口时。
服务器绑定到127.0.0.1:8080,客户端绑定到127.0.0.1:&lt;某些自由端口&gt; (因为您没有请求将客户端绑定到特定的端口)。 127.0.0.1:8080!= 127.0.0.1:<有些免费端口&gt;,所以没问题。
代码C的两个(可能多于两个)实例可以同时运行,而我不能运行代码A的两个实例。
您不能运行两个以上的“C”工作实例。将两个套接字绑定到同一IP地址和端口是不可能的。这就像试图给两个人一样的邮寄地址。
当代码A和代码C同时运行时,我通过谷歌浏览器访问了“http:// localhost:8008”,然后代码C打印了HTTP消息,而代码A没有。
当然。因为“C”管理绑定到127.0.0.1:8080,“A”不能并且死亡。
当我单独运行Code C时,代码B无法连接到它。
我不明白为什么。你得到什么错误?
答案 2 :(得分:0)
当我在一个文件中尝试使用上面代码中的一个修改
时我得到了以下错误..
所以我想知道发生了什么!所以我检查了一个不同的客户端程序,它仍然没有连接到Ruby客户端服务器。所以我想首先关注ruby服务器
示例套接字测试程序: http://sourceforge.net/projects/sockettest/
Ruby Server:
s = TCPServer.new("localhost", 20000)
while( c = s.accept)
while l = c.gets
puts l
end
end
Perl客户端:(pc.pl)
#!/usr/bin/perl
use IO::Socket::INET;
print "Client\n";
$c = IO::Socket::INET->new(PeerAddr => "localhost:20000") or die "$!";
while (<>) {
print $c $_
}
Perl Server:
#!/usr/bin/perl
use IO::Socket::INET;
print "Server\n";
$s = IO::Socket::INET->new(LocalPort => 20000, Type => SOCK_STREAM, Reuse => 1, Listen => 10, Proto => "tcp") or die "$!";
while ($c = $s->accept) {
print while <$c>;
}
Ruby客户端:
require "socket"
c = TCPSocket.new("localhost", 20000)
while l = gets
c.puts l
end
我家里连接了3个系统,将localhost替换为当前PC的实际IP解决了这个问题。 (WINDOWS中的ipconfig获取IP)
Ruby Server:
require "socket"
s = TCPServer.new("192.168.1.3", 20000)
while( c = s.accept)
while l = c.gets
puts l
end
end
Perl客户:
#!/usr/bin/perl
use IO::Socket::INET;
print "Client\n";
$c = IO::Socket::INET->new(PeerAddr => "192.168.1.3:20000") or die "$!";
while (<>) {
print $c $_
}
亚伯拉罕先生