2011-02-04 14 views
7

私はmIRCをポート1235でリッスンしていますが、ローカルホストサーバーのポートに接続するためにPHPスクリプトを作成しようとしました。PHPソケットは半分作業です

私のlocalhostは、mIRCが別のコンピュータ(lan内)で実行されているクリーンなApache + PHPです。

スクリプト働く右半分として:それは1235ポート 2)は、送信するに接続 1)$ I 2.1)が、何のMSGは受け取っていない他の側に(別名私は靴下読んイベントを取得しますが、 3)すべての着信メッセージを読み込みます。correclty 4) 'end'がメッセージのときに閉じます。 ドラムロール 5)while関数が存在しない場合にのみ機能します。 5.1)別名イニファイローディング。ソケットが閉じているときだけショーはここ

iはphp.netで見つかった簡単な例であるコードは、事前に感謝です:)

<?php 
//The Client 
error_reporting(E_ALL); 

$address = "192.168.1.101"; 
$port = 1235; 

/* Create a TCP/IP socket. */ 
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); 
if ($socket === false) { 
    echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n"; 
} else { 
    echo "socket successfully created.\n"; 
} 

echo "Attempting to connect to '$address' on port '$port'..."; 
$result = socket_connect($socket, $address, $port); 
if ($result === false) { 
    echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket)) . "\n"; 
} else { 
    echo "successfully connected to $address.\n<br>"; 
} 
$allow = true; 
$i = 0; 
while ($allow == true) 
{ 
    $i++; 
    echo "Sending $i to server.\n<br>"; 
    socket_write($socket, $i, strlen($i)); 

    $input = socket_read($socket, 2048); 
    if ($input == 'end') { 
     $allow = false; 
    } 
    echo "Response from server is: $input\n"; 
    sleep(5); 
} 

echo "Closing socket..."; 
socket_close($socket); 
?> 

これは私が得るものである「終了」を経由してエコーブラウザでは、「終了」と言った後に

ソケットが正常に作成されました。 '192.168.1.101'(ポート '1235')に接続しようとしました... 192.168.1.101に接続しました。サーバーに1を送信しています。サーバーからの応答は次のとおりです。サーバーからOK の応答は次のとおりです。最後

これはmIRCのである

テスト:89.152.172.21がです!私は60のための「読み取り」掛け、それは時間のために働いて左としていた場合 はBLOCKQUOTE

近い を読んで「送信N +サーバへの1」 が、これが唯一の靴下閉じた後に現れる(またはストーピングによってしばらく)

+1

あなたがそれを実行したときに吐き出されているものを投稿できますか?デバッグに役立つかもしれません。 – xil3

+0

は、 'echos'を吐き出すために投稿を更新しました:) – MoshMage

答えて

2

あなたは "プレーン" socket_write()socket_read()電話を持っています。残念なことにソケット関数は(BSDソケットから継承された動作)のデザインではが信頼できません。バッファの内容を必ずしもすべて書き込むとしません)

socket_write(:あなたはただ

PHPマニュアルの引用(...それは思ったほど奇数)socket_write()を呼び出し、それが実際にバイトを書くことを期待することはできません。ネットワークバッファーなどに応じて、バッファーは大きくなるものの、一定量のデータ(1バイトまで)だけが書き込まれることは有効です。データの残りの部分を意図的に送信することを忘れないように注意する必要があります。

書き込まれたバイト数を確認し、必要なものがすべて送信されるまで再試行を続ける必要があります。

読んでも同じです。読み上げ通話は、ご希望の電話番号(またはそれ以下)で読むことができ、となり、通話を再試行する必要があります。

一部のデータや送信を完了している可能性がありソケットどの見つけるために(均等にひどい)select()コールをブロックにソケットを設定し、ループ内で読み取り/書き込み呼び出し、または使用することを確認します。


あなたは、このような面倒くさないAPIをしたい場合は、信頼性が持っている、代わりにstreamsを使用すると、読み取り/書き込み。

PHPを必ずしも必要としない場合は、長寿命のネットワーク接続を持つプログラム用に特別に設計されたサーバー/環境であるNode JSをご覧ください。

+0

それは多くを説明します。また、このような詳細な回答をいただきありがとうございます。私はこれまで以上に機能することを期待していませんでした:) ストリームは簡単ですし、Node.jsもチェックします。 – MoshMage

0

変更

socket_write($socket, $i, strlen($i)); 

へ:

socket_write($socket, strval($i), strlen(strval($i))); 

PHPが文字列を要求するところでは、整数を指定しています。ドキュメントのノートの1から

+3

これは問題ではありませんか? – zanlok

+0

それでも、mIRCで0Rcvdバイトを得ます。 – MoshMage

0

:新しい行を受け取っされるまで http://php.net/manual/en/function.socket-write.php

一部のクライアント(例えば、FlashののXMLSocket)は、読み取りイベントが発生しません。

だからあなたのコードを変更してみてください:

socket_write($socket, $i, strlen($i)); へ: socket_write($socket, $i.'\n', strlen($i)+1);

+0

実際の改行を二重引用符で囲みます。 – igorw

関連する問題