2010-11-19 5 views
1

IRC 봇 스크립트에 문제가 있습니다.이를 필자의 Curl 전송 방법으로 구현했습니다.PHP - IRC 봇 스크립트 Hanging

IRC 봇이 IRC 채널에 메시지를 보내면 스크립트 끝에있는 모든 "echo"가 표시되지 않고 페이지가 중단되는 문제가 있습니다. 아파치 전체가 멈춘다.

<?php 

$ircServer = "///"; 
$ircPort = "6667"; 
$ircChannel = "#bots"; 

set_time_limit(0); 

$msg = $_POST['msg']; 
$paper = $_POST['paper']; 
$sizzor = $_POST['sizzor']; 
$hand = $_POST['hand']; 

$ircSocket = fsockopen($ircServer, $ircPort, $eN, $eS); 

if ($ircSocket) 
{ 

    fwrite($ircSocket, "USER Lost rawr.test lol :code\n"); 
    fwrite($ircSocket, "NICK Rawr" . rand() . "\n"); 
    fwrite($ircSocket, "JOIN " . $ircChannel . "\n"); 

ignore_user_abort(TRUE); // Noob Close down page 

    fwrite($ircSocket, "PRIVMSG " . $ircChannel . " :" . $msg . "\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"); 
      } 
} 
    echo $eS . ": " . $eN; 
} 
} 
?> 
if ($bootcontents == 'success') {  
echo '<center><marquee behavior="alternate" direction="left">Spinning xxx at ' . $power . '% power.</marquee></center>'; 

이 부분은 스크립트 동안 표시되지 않습니다 : 나는 전체 "에코"정보가 표시되지 않습니다 상단 위에 exit(); 기능을 추가하는 경우

if ($bootcontents == 'success') { 
    echo '<center><marquee behavior="alternate" direction="left">Spinning xxx at ' . $power . '% power.</marquee></center>'; 

페이지는 그냥 정지됩니다.

누군가 도와 드릴 수 있습니다.

+0

나는 루프가있는 것을 본다 : while (1). 이 루프를 벗어나는 종료 조건이 없으면 무한 루프가됩니다. – ryanlahue

+3

웹 서버를 통해 이런 식으로 시작하는 것은 좋지 않습니다. 또한 정상적인 서버는 사용자 및 NICK를받은 직후에 전송 될 가능성이있는 PING에 응답하지 않기 때문에 봇이 메시지를 보내지 않습니다. – ThiefMaster

+0

웹 페이지가 아닌 명령 줄에서 봇을 실행해야합니다. – Jocelyn

답변

0

당신은 무한 루프를 만드는 :

while (1) 
// ... 

이 루프 완료 할 수 없다, 당신은 출구 문 (같은이 break)를 사용하지 않았기 때문에. 따라서 무한 루프 이후의 코드는 절대로 실행되지 않습니다. 또한 많은 CPU 리소스를 사용하는 바쁜 루프이므로 전체 아파치 (및 컴퓨터)가 중단됩니다.

+0

왜 -1일까요? 대답은 정확해야합니다 (?) – apfelbox

+0

스크립트는 의도적으로 무한히 실행되도록 만들어졌습니다. 아마 그것이 당신이 downvote를 보는 이유입니다. 코드에서 이것은 의도에 의한 것이 분명합니다. 물론 설명은 OP가하는 실패의 일부입니다. 그래서 당신은 반대표를 얻습니다. – hakre

+0

hakre ... OP의 의도는 서버 출력을 잡기 위해 무한 루프를 갖는 것이지만 그의 설계는 완전히 잘못되었습니다 ... 그리고 OP가 질문을 한 적이 없기 때문에 위의 두 가지 응답이 절대 실행되지 않는 이유에 대한 대답으로 그의 디자인에 관한 것이지만 그 코드의 일부가 왜 작동하지 않는지에 대한 것입니다. 따라서 우리는 그의 디자인 의도가 무엇인지를 무시하고 코드 자체에 대해 의견을 말할 수 있습니다. – Populus

0

<?php ?> 태그에서 일부 라인을 남겨 두었으므로 태그 외부에있는 내용은 일반 텍스트로 처리됩니다. 당신은 ?> 태그 더 아래 폐쇄를 이동 고정하십시오 while(1) 루프는 종료 조건이 없기 때문에

 [this is the while(1) closing bracket] 
     } 
    // code past this line will never run, see below for details 
    echo $eS . ": " . $eN; 
    } 
} 
if ($bootcontents == 'success') { 
    echo '<center><marquee behavior="alternate" direction="left">Spinning xxx at ' . $power . '% power.</marquee></center>'; 
} 
?> <!-- closing tag goes here --> 

페이지 어쨌든 제대로를 작동하지 않을 : 내부 while 완료 후

while(1) { 
    while($data = fgets($ircSocket, 128)) { 
     // ... 
    } 
} 

을, 스크립트는 반복적 인 반복을 계속하여 무한 루프에 갇히게됩니다. (이런 종류의 허점을 찾아서 제거하지 않으면 서버가 멈추게됩니다).

마지막으로 PHP가 가장 적합한 도구는 아닙니다. 독립 실행 형 응용 프로그램을 사용하면 훨씬 편리 할 것입니다. 붙어 확인 롤 ... 영원히 ... 그것은 데이터를 수신하고 그 소켓을 통해 데이터를 얻지 못하고있어 어떻게 든 경우 ... 잘 당신이 거기에 붙어있는 때까지 스크립트가 실행

0
while($data = fgets($ircSocket, 128)) 

이 부분 블록, PHP 스크립트가 타임 아웃 될 때까지.

그 부분이 잡히지 않으면 while 회 돌이에 여전히 끼어있어 코드의 일부분을 실행하여 처리 할 수있는 방법이 없으므로 apfelbox와 Alex 모두 정확합니다. 그냥 완전히 설명하지 ...

무한 루프를 가지면서 코드를 외부에서 실행할 수 있으려면 코드를 캡처하고 실행하려는 "이벤트"를 잡아야합니다. 캡처하려는 모든 이벤트는 while 루프 내에 있거나 최소한 while 루프에서 서버의 입력을 구문 분석하고 올바르게 응답하는 함수로 전달되어야합니다.

이것을 수행하는 더 좋은 방법은 관찰자 패턴을 이용하는 것입니다.

커맨드 라인을 통해 실행해도 PHP로 IRC 봇을 만들지는 않을 것입니다 ...PHP는 장기 실행 응용 프로그램으로 실행되지 않습니다.