使用 PHP 连接到 IRC 服务器时连接超时
我正在尝试将 PHP 脚本连接到 IRC,但它总是超时。我在服务器上,所以我知道它已启动并正在运行,但我不知道问题出在哪里。
这可能是我的代码中的错误吗?
<?php
/**
* Configuration.
* Pretty self-explanatory
*/
$ircServer = "hub.malvager.com";
$ircPort = "6667";
$ircChannel = "#hackforums";
set_time_limit(0);
$ircSocket = fsockopen($ircServer, $ircPort, $eN, $eS);
if ($ircSocket)
{
fwrite($ircSocket, "USER Orgy orgy.test hfcoder :twBooter\n");
fwrite($ircSocket, "NICK OrgyBot|" . rand() . "\n");
fwrite($ircSocket, "JOIN " . $ircChannel . "\n");
while(1)
{
while($data = fgets($ircSocket, 128))
{
echo nl2br($data);
flush();
// Separate all data
$exData = explode(' ', $data);
// Send PONG back to the server
if($exData[0] == "PING")
{
fwrite($ircSocket, "PONG ".$exData[1]."\n");
}
}
}
}
else
{
echo $eS . ": " . $eN;
}
?>
更新:显然,它在某些服务器上成功运行,但在其他服务器上则不然。允许 fsockopen,set_time_limit 也是如此。我不知道问题出在哪里。
更新:这是跟踪路由:
traceroute to hub.malvager.com (69.164.201.185), 30 hops max, 40 byte packets
1 rtr-1.bluehost.com (69.89.16.1) 0.406 ms 0.418 ms 0.438 ms
2 ge-6-8.car2.SaltLakeCity1.Level3.net (4.53.42.5) 1.484 ms 1.515 ms 1.590 ms
3 ae-5-5.ebr1.Denver1.Level3.net (4.69.133.126) 35.117 ms 35.119 ms 35.270 ms
4 ae-2-2.ebr2.Dallas1.Level3.net (4.69.132.106) 39.978 ms 39.938 ms 39.939 ms
5 ae-3-80.edge4.Dallas3.Level3.net (4.69.145.141) 40.070 ms 40.046 ms ae-4-90.edge4.Dallas3.Level3.net (4.69.145.205) 40.040 ms
6 THE-PLANET.edge4.Dallas3.Level3.net (4.59.32.30) 40.171 ms 41.407 ms 40.698 ms
7 te7-2.dsr02.dllstx3.theplanet.com (70.87.253.26) 40.653 ms te9-2.dsr02.dllstx3.theplanet.com (70.87.253.30) 40.454 ms te7-2.dsr02.dllstx3.theplanet.com (70.87.253.26) 40.593 ms
8 * * 6e.ff.5746.static.theplanet.com (70.87.255.110) 40.537 ms
9 52.ff.5746.static.theplanet.com (70.87.255.82) 40.481 ms 40.472 ms 40.459 ms
10 li115-185.members.linode.com (69.164.201.185) 40.450 ms 40.171 ms 40.582 ms
以及挖掘:
; <<>> DiG 9.6.2-RedHat-9.6.2-0.BH <<>> hub.malvager.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34815
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 5, ADDITIONAL: 5
;; QUESTION SECTION:
;hub.malvager.com. IN A
;; ANSWER SECTION:
hub.malvager.com. 85419 IN A 69.164.201.185
;; AUTHORITY SECTION:
malvager.com. 85419 IN NS ns1.linode.com.
malvager.com. 85419 IN NS ns3.linode.com.
malvager.com. 85419 IN NS ns2.linode.com.
malvager.com. 85419 IN NS ns4.linode.com.
malvager.com. 85419 IN NS ns5.linode.com.
;; ADDITIONAL SECTION:
ns1.linode.com. 54252 IN A 69.93.127.10
ns2.linode.com. 51679 IN A 65.19.178.10
ns3.linode.com. 41439 IN A 75.127.96.10
ns4.linode.com. 26259 IN A 207.192.70.10
ns5.linode.com. 54441 IN A 109.74.194.10
;; Query time: 4 msec
;; SERVER: 74.220.195.27#53(74.220.195.27)
;; WHEN: Thu Sep 23 16:32:21 2010
;; MSG SIZE rcvd: 227
NETCAT:
nc:连接到 hub.malvager.com 端口 6667 (tcp) 失败:连接超时< /代码>
I'm trying to connect my PHP script to IRC, but it keeps timing out. I'm on the server, so I know it's up and running, I can't tell what the problem is.
Could it be an error in my code?
<?php
/**
* Configuration.
* Pretty self-explanatory
*/
$ircServer = "hub.malvager.com";
$ircPort = "6667";
$ircChannel = "#hackforums";
set_time_limit(0);
$ircSocket = fsockopen($ircServer, $ircPort, $eN, $eS);
if ($ircSocket)
{
fwrite($ircSocket, "USER Orgy orgy.test hfcoder :twBooter\n");
fwrite($ircSocket, "NICK OrgyBot|" . rand() . "\n");
fwrite($ircSocket, "JOIN " . $ircChannel . "\n");
while(1)
{
while($data = fgets($ircSocket, 128))
{
echo nl2br($data);
flush();
// Separate all data
$exData = explode(' ', $data);
// Send PONG back to the server
if($exData[0] == "PING")
{
fwrite($ircSocket, "PONG ".$exData[1]."\n");
}
}
}
}
else
{
echo $eS . ": " . $eN;
}
?>
UPDATE: Apparently, it's successfully working on SOME servers, but not others. fsockopen is allowed, as is set_time_limit. I can't figure out what the problem is.
UPDATE: Here's a trace route:
traceroute to hub.malvager.com (69.164.201.185), 30 hops max, 40 byte packets
1 rtr-1.bluehost.com (69.89.16.1) 0.406 ms 0.418 ms 0.438 ms
2 ge-6-8.car2.SaltLakeCity1.Level3.net (4.53.42.5) 1.484 ms 1.515 ms 1.590 ms
3 ae-5-5.ebr1.Denver1.Level3.net (4.69.133.126) 35.117 ms 35.119 ms 35.270 ms
4 ae-2-2.ebr2.Dallas1.Level3.net (4.69.132.106) 39.978 ms 39.938 ms 39.939 ms
5 ae-3-80.edge4.Dallas3.Level3.net (4.69.145.141) 40.070 ms 40.046 ms ae-4-90.edge4.Dallas3.Level3.net (4.69.145.205) 40.040 ms
6 THE-PLANET.edge4.Dallas3.Level3.net (4.59.32.30) 40.171 ms 41.407 ms 40.698 ms
7 te7-2.dsr02.dllstx3.theplanet.com (70.87.253.26) 40.653 ms te9-2.dsr02.dllstx3.theplanet.com (70.87.253.30) 40.454 ms te7-2.dsr02.dllstx3.theplanet.com (70.87.253.26) 40.593 ms
8 * * 6e.ff.5746.static.theplanet.com (70.87.255.110) 40.537 ms
9 52.ff.5746.static.theplanet.com (70.87.255.82) 40.481 ms 40.472 ms 40.459 ms
10 li115-185.members.linode.com (69.164.201.185) 40.450 ms 40.171 ms 40.582 ms
And the dig:
; <<>> DiG 9.6.2-RedHat-9.6.2-0.BH <<>> hub.malvager.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34815
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 5, ADDITIONAL: 5
;; QUESTION SECTION:
;hub.malvager.com. IN A
;; ANSWER SECTION:
hub.malvager.com. 85419 IN A 69.164.201.185
;; AUTHORITY SECTION:
malvager.com. 85419 IN NS ns1.linode.com.
malvager.com. 85419 IN NS ns3.linode.com.
malvager.com. 85419 IN NS ns2.linode.com.
malvager.com. 85419 IN NS ns4.linode.com.
malvager.com. 85419 IN NS ns5.linode.com.
;; ADDITIONAL SECTION:
ns1.linode.com. 54252 IN A 69.93.127.10
ns2.linode.com. 51679 IN A 65.19.178.10
ns3.linode.com. 41439 IN A 75.127.96.10
ns4.linode.com. 26259 IN A 207.192.70.10
ns5.linode.com. 54441 IN A 109.74.194.10
;; Query time: 4 msec
;; SERVER: 74.220.195.27#53(74.220.195.27)
;; WHEN: Thu Sep 23 16:32:21 2010
;; MSG SIZE rcvd: 227
NETCAT:
nc: connect to hub.malvager.com port 6667 (tcp) failed: Connection timed out
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
你有一些错误。
有bug,因为严格检查首先爆炸结果,你通过空格字符爆炸,并且在IRC实现协议中,所有命令必须以换行符终止,然后服务器发送如果您是
"PING\n"
而不是"PING"
那么您的$exData
数组就处于这种状态。那么您的
$exData[0] == "PING"
为 false,因为"PING"
不等于"PING\n “
。好的解决方案不是将
"\n"
添加到解析器中的命令末尾,因为"\n"
不仅仅是换行符(对于较差的 IRC 协议实现,我建议这样做,你永远不知道IRC协议开发人员可能使用什么换行符,想想Delphi INDY Buggy IRC Server Control),更好的解决方案是不检查她。我将把
while($data = fgets($ircSocket, 128))
更改为while ($data = fgets($ircSocket))
,因为在长服务器中名称可以简单地溢出 128 字节。并且您的
fwrite($ircSocket, "JOIN " . $ircChannel . "\n");
行没有完全按照您的要求执行,因为您的JOIN
命令已发送在USER
和NICK
命令之后,服务器在用户注册之前解析您的请求,如果用户未注册,您可以JOIN
到频道、IRC服务器不要对失败的命令进行排队,因为这没有任何意义。最佳实践是在从服务器收到MOTD
命令之后以及收到来自频道的 left 命令之后发送JOIN
命令,如果您想实现一些功能,例如 <代码>自动加入。关于你的脚本设计,如果你编写简单的机器人,那么我在这个主题中没有什么可说的,但如果你计划编写一些大的代码,你应该以其他方式设计你的脚本。您必须将某些层(例如 IRC 协议实现和 IRC 机器人操作)分开。您应该使用一些类将 IRC 协议的责任转移给她,因为在更大的代码中,将 IRC 协议控制与您的机器人操作代码混合在一起是很好的技术债务。
You have some errors.
Is buggy, because checking strictly first explode result, you exploding by space character and in IRC implementation protocol all commands must be terminated by newline character then server send to you
"PING\n"
not"PING"
then your$exData
array is in this state.Then your
$exData[0] == "PING"
is false because"PING"
is not equal to"PING\n"
.Good solution is not add
"\n"
to the end of command in parser because"\n"
is not only newline marker (for poor IRC Protocol implementation i recommend this, you never know what newline marker IRC protocol developer may use, think about Delphi INDY Buggy IRC Server Control), better solution is not checking her.I will change the
while($data = fgets($ircSocket, 128))
, to thewhile ($data = fgets($ircSocket))
, because in long server names you can simply overflow 128 bytes.And your
fwrite($ircSocket, "JOIN " . $ircChannel . "\n");
line don't doing exactly what you want, because yourJOIN
command was sended after theUSER
andNICK
command then server parse your request before user was registered and if user is not registered you canJOIN
to channel, IRC servers don't QUEUE failed command because this don't have any sense. The best practice of this is sendJOIN
command after theMOTD
command was received from the server and after the left from channel command was received too if you want implement some functionality likeAUTOJOIN
.About your script design, if you writing simple bot then i don't have any thing to say in this topic, but if you plan write some big piece of code you should design your script in other way. You must separate some layers like IRC Protocol implementation and your IRC Bot actions. You should use some class to move responsibility of IRC Protocol into her, because in bigger piece of code mixing IRC Protocol control with your bot actions code is nice Technical debt.
netcat
nc hub.malvager.com 6667
如果您的结果是:
PHP.ini
文件来调整fsockopen
设置,如果问题尚未解决(我认为使用默认的.ini
文件,您的脚本将运行良好)。如果您的结果代表某些连接错误,有些人会这样想:
执行
tracert hub.malvager.com
并将结果发布到您的问题中,那么我必须阅读此内容并更新我的答案。如果您正在使用 POSIX 进行
dig hub.malvager.com
并将结果发布到您的问题中,那么我必须阅读本文并更新我的答案。如果您正在WINDOWS上进行
nslookup hub.malvager.com
并将结果发布到您的问题中,那么我必须阅读本文并更新我的答案。如果你想单独分析这个结果,从你的观点来看,方便的是我的这个命令的结果,然后我发布这个。
dig hub.malvager.com
的结果:tracert hub.malvager.com
在 POSIX 上的结果:netcat
nc hub.malvager.com 6667
If your result is:
PHP
version from SOURCE FILES (this is important because in binary versions from apt or something versions is deprecated) from php.netPHP.ini
file to tunefsockopen
settings if problem not has solved yet (i think with default.ini
file your script will be working good).If your result representing some connection error, some think like this example:
Do
tracert hub.malvager.com
and post results into your question, then i must read this and update my answer.If you are working on POSIX do
dig hub.malvager.com
and post results into your question, then i must read this and update my answer.If you are working on WINDOWS do
nslookup hub.malvager.com
and post results into your question, then i must read this and update my answer.If you want analyze this result alone, handy from your point is my results of this command then i post this.
Result of
dig hub.malvager.com
:Result of
tracert hub.malvager.com
on POSIX:服务器可能需要身份响应。另外,我运行了该脚本,它连接得很好。也许是防火墙问题。
The server might require a ident response. Also, I ran that script, it connected fine. Maybe its a firewall issue.
您是否尝试过使用 telnet 来模拟您的机器人的行为并看看会发生什么?连接、输入(或复制粘贴)您的机器人将输出的内容,然后盯着屏幕几分钟。
Have you tried using telnet to simulate your bot's behavior and see what happens? Connect, type (or copy-paste) exactly what your bot would output and stare at the screen for a few minutes.
这段
代码有一个完美的工作IRC服务器。我会走这条路。
PS:如果你不喜欢它,请保持友善,不要写下来。谢谢
this
code has a perfect working IRC server. I would go this way.
PS: If you don't like it, be nice and don't wote it down. Thanks
听起来您被阻止是因为您没有设置 IDENT。
侦听端口 113 以查看是否有来自IRC 服务器。
另外这是一本关于 Mirc 如何处理 ident 请求的好读物,因此您可以很容易地创造出一些东西来使其发挥作用。
Sounds like you are being blocked because you don't have IDENT set up.
Listen on port 113 to see if there is an Ident request from the IRC server.
Also this is a good read for how Mirc handles ident requests so you can easily whip something up to make it work.
1) 如果服务器发送带有消息的 ping,您应该回复 pong,后跟相同的消息。
2) 不时地(每30秒左右)向服务器发送一条ping消息。如果您在几分钟内没有收到回复,您可能会认为客户端已从服务器超时并应该重新连接。
1) If the server sends a ping with a message, you should reply with a pong followed by the same message.
2) From time to time (every 30 seconds or so) send a ping message to the server. If you don't get a reply in a couple of minutes, you can probably consider that the client has timed out from the server and should reconnect.
根据rfc1459,IRC 协议中消息的结尾是“\r\n”,而不仅仅是“\n”。因此,某些服务器实现可能会拒绝您的消息。
The end of message in the IRC protocol according to rfc1459 is ¨\r\n¨ not just ¨\n¨. Some server implementations might reject your messages because of that.
Telnet 指示 malvager.com 应该这样写,端口 6667
Telnet indicates it should be written this way for malvager.com, port 6667
您是从本地计算机还是网络服务器运行此机器人?如果它来自您的网络服务器,则可能是 malvager.com 阻止了您的网络服务器,而其他 irc 服务器则将其解锁。
我在其他 IRC 网络上也遇到过这个问题,事实证明,其他人也使用了我用来托管僵尸网络的同一托管提供商,这需要 IRC 服务器阻止我的主机的 IP。
我会询问 malvager.com 管理员您连接的 IP 地址是否被阻止。
还可以尝试
$ircSocket = fsockopen($ircServer, $ircPort, $eN, $eS, 30);
编辑:
我使用 bluehost,看起来你也这样做。我的 irc 在他们的服务器上工作时遇到问题,我在实时聊天中与他们交谈。他们提到他们不允许 irc 机器人进入他们的网络,所以他们封锁了大部分网络。但他们提到,如果有人溜过并被他们发现,他们将暂停你的帐户。
Are you running this bot from your local machine or your webserver? If it is from your webserver it could be that malvager.com has your webserver blocked while other irc servers have it unblocked.
I have had this issue on other IRC networks and it turns out, other people have used the same hosting provider I use to host botnets which required the IRC server to block the IP from my host.
I would ask a malvager.com admin if the IP address you are connecting from is blocked.
Also try
$ircSocket = fsockopen($ircServer, $ircPort, $eN, $eS, 30);
EDIT:
I use bluehost and it looks like you do too. I was having issues with my irc working on their servers and I spoke to them in Live Chat. They mentioned they don't allow irc bots on their network so they have most of the networks blocked. They mentioned however if one slips by and they catch it, they will suspend your account.
我记得在 mIRC 时代做过一些机器人。
问题总是出在我以前的换行符上
留言后发送。
据我记得,字符是 #30 和 #32 之类的。
为什么不尝试它们而不是\n。有些服务器很漂亮
对这个问题比较敏感。
此外,乒乓球还必须在
ping,这非常重要。
玩得开心!
I remember doing some bots back in the mIRC era.
The problem were always the line breaks i used to
send after the message.
As far as i remember, the chars vere #30 and #32 or such.
Why not try them instead of \n. Some servers are pretty
sensitive to this issues.
Also the pong has to be replied with the text after the
ping, thats very important.
Have fun!
bluehost.com
托管阻止 IRC 连接到此 IRC 服务器,这是已检查的信息。bluehost.com
hosting blocking IRC connections to this IRC server, this is checked information.