2016-05-10 6 views
0

- 私、コードのthatsがデータを受信以下の通りです:socket_recvは1448バイトのみを受信して​​いますか?私のクライアントがサーバに送信する完全なデータを受信する<code>socket_recv</code>といくつかの問題を抱えて

while(true) { 

     $changedSockets = $this->sockets; 
     $result = socket_select($changedSockets,$write,$except,0); 

     foreach($changedSockets as $socket){ 

      $buffer = ''; 
      $message = ''; 

      $bytes = @socket_recv($socket, $buffer, 4096, 0); 


       echo "Lenght: (".$bytes.length.")"; 


      if ($bytes === false) { 
      $error = self::getLastError($this->socket); 
      trigger_error('Failed to receive data from client #'.$client->id.': '.$error->message.' ['.$error->code.']', E_USER_WARNING); 
      continue; 
      } 

      $len = ord($buffer[1]) & 127; 

      $masks = null; 
      $data = null; 

        if ($len === 126) { 
         $masks = substr($buffer, 4, 4); 
         $data = substr($buffer, 8); 
        } 
      elseif ($len === 127) { 
         $masks = substr($buffer, 10, 4); 
         $data = substr($buffer, 14); 
        } 
      else { 
         $masks = substr($buffer, 2, 4); 
         $data = substr($buffer, 6); 
        } 

        for($index = 0; $index < strlen($data); $index++) { 
         $message .= $data[$index]^$masks[$index % 4]; 
        } 

        if ($bytes == 0) { 
         $this->disconnectClient($socket); 
        } 

     } 
     } 
     } 

このコードは非常にうまく動作しますが、一つの問題で:I場合5800文字を超えるテキストを送信すると、私のコードはフルテキスト(小さな部分のみ)を受け取ることはありません。いただきましたが、私は持っているどのように多くのバイトを確認するには、以下のコードを挿入して起こっている表示するには

が来る:これにより

$bytes = @socket_recv($socket, $buffer, 4096, 0); 
echo "Lenght: (".$bytes.length.")"; 

を私はあなたがバイトのサイズは5800文字未満のテキストを送信するときにことがわかりクライアントが送信するバイトと同じサイズ。テキストが5800文字を超えると、socket_recvの長さは1448文字にとどまります。 (私はそれがより多くの文字を取得します高い値に値4096を変更するが、私が上げた場合、PHPは、メモリの問題行う場合)

私が使用してのように多くのことを試してみてください。この問題を解決するには:MSG_DONTWAITMSG_WAITALLwhile($bytes > 0){ ... }を。しかし、それらはすべてコードの残りの部分(socket_recv以下)がもはや実行されないように無限ループに入ります。

どうすればこの問題を解決できますか?私はこの問題を解決するために私の脳をラッキングされたが(私はlocalhostでwampserverで - 私のテスト)

解決策

は、私は一時的な解決策について考えた:

場合私たちは5800文字よりも大きいテキストを送ることはできません、私は の文字を5800 文字より小さな文字にカットするコードをクライアント側に作成して、これらの部分をソケットに別々に パラメータは、このエントリが切り捨てられ、ソケット内では がそれらをフィルタリングして文字に参加しようとする可能性があることを示しています。

+0

あなたはwebsocketサーバーを実装しているようです。プレーンなソケットがどのように機能するかについて多くの知識がなくても、最初からこれをやりたいのですか?メッセージ全体を取得するまで、メッセージを解析して 'recv()'を続ける必要があります。 – CodeCaster

+0

@CodeCaster、私は下の答えとして投稿された私のイデアを試して、とてもうまくいきました。そして、私のコードは5800文字以上のメッセージを受信できます。 – Lacrifilm

+0

@RyanVincent私はこれらのライブラリを知っていますが、少し問題があります。ライブラリの多くは私が使用しないものがあります。私はプライベートチャットアプリケーションを作成しようとしていて、いつもソケットに関する好奇心が...初心者からの挑戦よりも優れたものはありません。D – Lacrifilm

答えて

0

私はその間に多くのテストを実現しました。私はいくつかのことを認識しました。 、Ó[ÁhÒß

メッセージは

彼らはあなたがのようなものが表示されます$buffer変数でechoを実行する場合、彼らは、標準RFC 6455で暗号化されているサーバー上で受信されたメッセージを受信した暗号化されています。 ..Example:あなたは別のハッシュを参照してください、彼らは暗号化標準に従って、元you'll再びその文字列を挿入する場合は、文字列stackoverflowについては

はyou'll、iuj87xzを参照してください十分なもの:文字列の場合stack stack私は両方とも同じハッシュ(rrtfghrrtfgh)ですが、ソケットにもう一度送ってみると、前と同じdiferenteハッシュが表示されますが、ハッシュは両方とも同じです(mmjshtmmjsht )。

メッセージは、私は私の画面上$bufferを表示し、10000を超える文字でテキストを送信すると、私はforeach($changedSockets as $socket)それはのすべての部分まで呼ばれるように続けていることがわかりブロック

に受信されていますメッセージが配信されました。

自分のコードが表示されたら、新しいメッセージがすべて復号化されることがわかります。しかし、私は問題を抱えていました。暗号化された最初のブロックメッセージは、(ソケットに送信したテキストを読んで)明確に読むことができましたが、これは他のブロックでは起こりません。私は最初のブロックで別の何かに気づくことができ、変数$bufferに含まれるハッシュを分析

、例:Hello Hello Hello....(repeated 10000X)

ブロック1:þ@¨¿7ÀlÓ[Ç)×RÄeÐÀlÓ[Ç)×RÄeÐÀlÓ[Ç)×RÄeÐÀlÓ[Ç)×RÄeÐÀlÓ[Ç)×RÄeÐÀlÓ[Ç)

ブロック2のサーバに、このテキストを送信できます: ×RÄeÐÀlÓ[Ç)×RÄeÐÀlÓ[Ç)×RÄeÐÀlÓ[Ç)×RÄeÐÀlÓ[Ç)×RÄeÐÀlÓ

ブロック1復号化さ:Hello Hello Hello Hello...

ブロック2復号化ed:LLE LLE LLE LLE LLE...

違いがありますか?他のブロックには存在しないブロック1内に異なるエントリコードがあるように見えます。それは私に、ハッシュの前にブートコードを持っているbase64に変換されたイメージを思い出させました:data:image/png;base64,......そしてこれは動作しないので、ブートコードなしでハッシュの一部を持っていません。

解決策

私はこのような、そのメッセージの長さでソケットにメッセージを送ることができます。サーバー側の"16049" Hello Hello Hello....を私はこの金額を取ると私の長さであること4096ことによってそれを分割したいですSocket_Recvで、結果は4になります。これは、完全なメッセージのすべてのブロックを受け取るために必要な繰り返しの回数になります。

次に、最後のブロックを受け取るまで(私はハッシュを取って、$bufferを連結しています)、メッセージを復号化するコードを実行しません。

私はこのコードをテストしていませんが、コードのテストが終了したら、ここに戻って完全なコードを投稿します。

関連する問題