2015-12-15 13 views
5

bayt dizisi uzunluğunu almak ve ben böyle bir kod şey kullanıyorum, bir şüphem:C# soket i C# prizler kullanmayı öğrenmeye çalışıyorum

byte[] data = new byte[64]; 
int length = 0; 
length = sock.Receive(data); 
//more code... 

Yani, byte[] verilerdir İstenen verilerle doldurulur ve dizideki sol boşluk 0s ile doldurulur, byte[] belleğe tamamen ayrılmış mı (tümü 64 bayt)? Öyleyse, byte[]'u gerçek gönderilen verilerle aynı boyutta yapmanın bir yolu var mı?

+0

Ağdan ne kadar veri geldiğini görmek için 'sock.Available' kutusunu işaretleyebilirsiniz. Not, daha sonra daha fazla veri alabilirsiniz. – ebyrob

+0

Evet, 64 bayt ayrıldı. Çağrı almadan önce tahsis edilirler, bu nedenle verilerin gerçek boyutunun ne olacağını bilen var mı? Hiç görmediğiniz bir paketi sarmak için bir parça sicimi doğru uzunlukta kesmek gibi olurdu. Kristal küreye ihtiyacın var. – phoog

cevap

1

Sadece geldi ne kadar veri anlamak için Receive dönüş değeri kullanmak gerekir. İsterseniz Array.Resize kullanarak arabelleği kısaltabilirsiniz, ancak normalde bir şeyin yanlış olduğuna dair bir işaret olabilir. Ayrıca, TCP'nin bir bayt akışı olduğunu ve ileti sınırlarını koruduğunu unutmayın.

+0

"byte [] data = new byte [1048576]" kullanmayı denedim ve CPU kullanımı 0,4'ten 2,7'ye ve 6mb'den 20mb'ye bellekte çıktı, bu yüzden ayrıldı. Sorun şu ki, aldığım kadarıyla alınan verilerin boyutunun ne olduğunu bilmiyorum ve aldığımdan önce gönderilen verilerin en azında bir byte [] olması gerek. her iki şekilde nasıl yapılacağını biliyorum. Hayal edebileceğim tek çözüm, müşterinin azami sayıda veri göndermesini ve daha fazlasını yapmamasını sağlamak. – null

+0

@ user3324670 İstemciden ne beklendiğini bilmek ağ programlamasının büyük bir parçasıdır. Ayrıca, mevcut verinin sadece bir kısmını okuyabilir ve gerisini almak için tekrar okuyabilirsiniz. (okumanın altında ve üstünde OK, mesajı aldığın zaman bir kez daha topla) – ebyrob

+0

Ne kadar çok şeyin geleceğini bilmenin tek yolu, diğer tarafın sana söylemesini sağlamaktır, örneğin kaç bayt istediği ile bir tamsayı göndererek şimdi gönder. Bu ortak bir yaklaşımdır. – usr

3

Zaten gelip ne görmek için sock.Available kontrol edebilirsiniz (şimdiye kadar)

byte[] data = new byte[sock.Available]; 
int length = sock.Receive(data); 
//more code... 

Not:. Eğer yoksa genellikle daha mantıklı ağdaki bir sonraki geliyor biliyor olabilir veya olmayabilir yana İlk önce sadece bir başlık (boyut bilgisi ile) okuyun veya gerektiğinden daha fazla alan ayırın ve bir kaydın sonuna ulaşılana kadar .Recieve()'u birden çok kez arayın.

Not: Bu kod zaten orada almak için bazı veriler olduğunu ve hazır olmak için bazı verilerin yararlı miktarı için yeterince bekledik biliyorum varsayar.

Eğer uzunluk üstbilgileri kullanmayı tercih ederseniz, .Available, kısmi bir üstbilgiyi okumamıza ve güzel bir şekilde yeniden birleştirmek zorunda kalmanıza yardımcı olabilir. (Bu durumda yalnızca büyük iletiler el ile yeniden birleştirmeye ihtiyaç duyabilir)

+0

Bunun nasıl yardımcı olduğundan emin değilsiniz. Ya mevcut ise sıfırdır? – usr

+0

@usr Ardından okunacak veri yok ... Ayrıca, mevcut baytlar okuma ve kontrol arasında değişebilir. – ebyrob

+0

Oh, tam olarak aradığım şey şu ki, bunu bilmiyordum: P, Teşekkürler. – null

2

Normalde belirtildiği gibi daha az bayt döndükten sonra anlatılacağı söylenir. Aşağıda belirtildiği gibi çok sayıda bayt okumasını sağlayan bir geçici çözüm işlevine bakın - temel olarak geçirilen arabelleğin boyutu. İşlev here'dan alınmıştır.

/// Reads data into a complete array, throwing an EndOfStreamException 
/// if the stream runs out of data first, or if an IOException 
/// naturally occurs. 
/// </summary> 
/// <param name="stream">The stream to read data from</param> 
/// <param name="data">The array to read bytes into. The array 
/// will be completely filled from the stream, so an appropriate 
/// size must be given.</param> 
public static void ReadWholeArray (Stream stream, byte[] data) 
{ 
    int offset=0; 
    int remaining = data.Length; 
    while (remaining > 0) 
    { 
     int read = stream.Read(data, offset, remaining); 
     if (read <= 0) 
      throw new EndOfStreamException 
       (String.Format("End of stream reached with {0} bytes left to read", remaining)); 
     remaining -= read; 
     offset += read; 
    } 
} 

Söyleyecek ilk okuyan bu yöntemi kullanabilirsiniz takip edecek bayt sayısını temsil etmelidir 2 byte tamsayı. Sonra bir kez daha okuyorsunuz, ancak şimdi , iki byte tamsayıda belirtildiği gibi çok sayıda bayt okuyor. ve sonra verileri kendisi -

Ama bunun işe yaraması için, açıkça gönderen ilk takip edecek verilerin uzunluğunu temsil eden iki bayt tamsayı göndermek zorundadır.

Böylece temelde boyut iki bir bayt dizi işlevi yukarıda çağrı ilk (veri uzunluğunu elde etmek için) ve daha sonra bu 2 bit tamsayı (veri almak için) 'de gösterildiği gibi boyutu olan bir bayt dizisi ile.

NetworkStream'dan okumak için bunu kullanabilirsiniz. Bu konuyla ilgili daha fazla reading.

+0

Böyle bir şey, sadece 2bayt okuma ve tamsayıya dönüştürme ve daha sonra – null

+0

@ user3324670 gönderdiği boyutu okuma: Evet, bu şekilde gitmelisiniz; –

+0

okumak için yukarıdaki işlevi kullanabilirsiniz biraz endişeli abuout, eğer birisi yanlış bir şey gönderilirdi eğer bir şey gönderilemezse (sanırım bir sunucu güvende olursam çok önemsemem gerekir) diğer şeyler). – null

İlgili konular