2010-01-03 2 views
1

Мне нужна помощь со следующим. это связано с асинхронными сокетами.C# void ReceiveData (IAsyncResult iar)

от отправителя:

string stringData = "Welcome to my server server server"; 
byte[] message1 = Encoding.ASCII.GetBytes(stringData); 

//MessageBox.Show(message1.Length.ToString()); 

client.BeginSend(message1, 0, message1.Length, SocketFlags.None, new AsyncCallback(SendData), client); 

здесь, как можно видеть, message.length можно найти.

-

на клиенте:

Socket remote = (Socket)iar.AsyncState; 
    int recv = remote.EndReceive(iar); 
    string stringData = Encoding.ASCII.GetString(data, 0, recv); 

мой вопрос, есть ли способ, чтобы получить доступ к фактической длине переданных данных и на основе этих данных вызова ПРИИХ до полного сообщение не будет получено ?

ответ

7

No - TCP/IP - это поток протокол. Просто потому, что вы отправили данные одним вызовом, это не означает, что он будет отправлен как один пакет или что он не будет объединен с другими пакетами. Другими словами, отправка «X» тогда «Y» эквивалентна отправке «XY» - они могут быть переданы с теми же самыми пакетами, неразличимыми на другом конце.

Если вам нужна идея отдельного «сообщения» в потоке, вы должны префикс данных несколькими байтами, явно указывающими его длину. (Альтернативой является использование разделителя, но я предпочитаю использовать префикс длины - он позволяет легче узнать, сколько данных вы получили, вам не нужно беспокоиться о том, чтобы начать использовать следующее сообщение, и вам не нужно беспокоиться об исключении разделителя в той или иной форме.)

+0

вместо префикса я только что реализовал цикл, как указано здесь http://stackoverflow.com/questions/582550/c-begin-endreceive-how -do-я-читать-большой-данных. Кажется, это работает! :) – iTEgg

+0

Вы можете только продолжать цикл, если хотите получать все данные до тех пор, пока сокет не будет закрыт - иначе вы не узнаете, когда вы на самом деле видели все это. Это нормально, если вы просто делаете один запрос/ответ на соединение, но он не работает для протокола типа «разговор» с несколькими сообщениями в каждом направлении. –

0

Только если что-то передается для связи длины - либо предварительно отложите длину сообщения, либо отправьте какой-либо символ терминатора.

Смежные вопросы