php değişken uzunluk paketler

4 Cevap php

Ben UDP ile benim sunucuya gönderilen paketleri alıyorum. Ben verileri okumak için socket_read kullanıyorum ve gayet güzel ilerliyor. Ancak ben bir hata içine çalıştırmak. Benim durumumda socket_read için uzunluğu parametre her zaman aynı değildir. Verinin uzunluğu 50-150 bayt yerde arasında olabilir. Sabit kalır bir şey veri seti \ x00 bayt ile sona erdi olmasıdır. Nasıl okuma işlevi her zaman bu bayt karşılaşmak kadar okumak almak istiyorsunuz? Zaten PHP_NORMAL_READ bayrağı denedim, ama docs sadece gerçekten ben (benim veri için çalışmıyor denedim) istediklerini hangi değil \ n, \ r biter söylüyorlar. Aynı zamanda, bu length parametresi açıklamasında socket_read devletler için php sayfa,

The maximum number of bytes read is specified by the length parameter. Otherwise you can use \r, \n, or \0 to end reading (depending on the type parameter, see below).

Türü / 0 byte hakkında hiçbir şey söylemez. Onun belgelerin bir parçası gibi eksik. Ne yapmam gerekiyor bana veriler için bir sınırlayıcı belirtmek sağlayacak ya bir fonksiyondur, otomatik olarak kullanılabilir soketten tüm verileri okuyacak. Orada bir socket_recv işlevi çözüm ancak belgesiz olabilir ve ben nasıl çalıştığını bilmiyorum.

Şimdiden teşekkürler.

4 Cevap

Eğer doğru anlamak, sorunun veri miktarı değişkendir ve ne zaman durdurmak için bilmiyorum varlık okumak için daha fazla veri, hiçbir kalmayıncaya kadar bir soketten veri okumak istiyorum.

Ilgili kılavuz sayfasına göre (http://php.net/socket_read):

Note: socket_read() returns a zero length string ("") when there is no more data to read.

Eğer sıfır uzunlukta bir dize vurmak kadar byte-by-byte okuyarak değişken uzunlukta veri ile başa çıkmak mümkün olmalıdır:

while (($currentByte = socket_read($socket, 1)) != "") {
    // Do whatever you wish with the current byte
}

Eğer geçen ne olursa olsun uygulama mesajı için "kaydının sonuna" eriştiyseniz okuma yükü ile ilgili uygulama tanımak gerekir. Okuma keyfi uzunluğu bekliyoruz.

Birden bir mesaj içine okur akışı çalışıyorsanız okumak paketlerin sırasını garanti edemez gibi UDP, kullanımı ile dikkatli, her iki eş tarafından gönderilen düzen vardır. Bu durumda TCP soketi kullanmanızı tavsiye ederiz.

Eğer böyle bir şey denedim hav:

do {
    echo socket_read($handle,1024);
    $status = socket_get_status($handle);
} while($status['unread_bytes']);

Sadece senin durumunda işe yarayabilecek başka bir yaklaşım geldi:

<?php
  function tftp_fetch($host, $filename)
  {
    $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);

    // create the request packet
    $packet = chr(0) . chr(1) . $filename . chr(0) . 'octet' . chr(0);
    // UDP is connectionless, so we just send on it.
    socket_sendto($socket, $packet, strlen($packet), 0x100, $host, 69);

    $buffer = '';
    $port = '';
    $ret = '';
    do
    {
      // $buffer and $port both come back with information for the ack
      // 516 = 4 bytes for the header + 512 bytes of data
      socket_recvfrom($socket, $buffer, 516, 0, $host, $port);

      // add the block number from the data packet to the ack packet
      $packet = chr(0) . chr(4) . substr($buffer, 2, 2);
      // send ack
      socket_sendto($socket, $packet, strlen($packet), 0, $host, $port);

      // append the data to the return variable
      // for large files this function should take a file handle as an arg
      $ret .= substr($buffer, 4);
    }
    while(strlen($buffer) == 516);  // the first non-full packet is the last.
    return $ret;
  }
?>

Bu yaklaşım hakkında en ilginç bölümü ise:

do
...
while(strlen($buffer) == 516);  // the first non-full packet is the last.