c#endread怎么打印出来,C#中开始/ EndReceive - 如何阅读大量数据?

本文探讨了如何使用异步IO从套接字中读取超过缓冲区大小的数据包。通过不断调用BeginReceive直到EndReceive返回0来实现完整的数据接收,并讨论了使用数据包长度前缀或结束符作为解决方案的可能性。

When reading data in chunks of say, 1024, how do I continue to read from a socket that receives a message bigger than 1024 bytes until there is no data left? Should I just use BeginReceive to read a packet's length prefix only, and then once that is retrieved, use Receive() (in the async thread) to read the rest of the packet? Or is there another way?

edit:

I thought Jon Skeet's link had the solution, but there is a bit of a speedbump with that code. The code I used is:

public class StateObject

{

public Socket workSocket = null;

public const int BUFFER_SIZE = 1024;

public byte[] buffer = new byte[BUFFER_SIZE];

public StringBuilder sb = new StringBuilder();

}

public static void Read_Callback(IAsyncResult ar)

{

StateObject so = (StateObject) ar.AsyncState;

Socket s = so.workSocket;

int read = s.EndReceive(ar);

if (read > 0)

{

so.sb.Append(Encoding.ASCII.GetString(so.buffer, 0, read));

if (read == StateObject.BUFFER_SIZE)

{

s.BeginReceive(so.buffer, 0, StateObject.BUFFER_SIZE, 0,

new AyncCallback(Async_Send_Receive.Read_Callback), so);

return;

}

}

if (so.sb.Length > 0)

{

//All of the data has been read, so displays it to the console

string strContent;

strContent = so.sb.ToString();

Console.WriteLine(String.Format("Read {0} byte from socket" +

"data = {1} ", strContent.Length, strContent));

}

s.Close();

}

Now this corrected works fine most of the time, but it fails when the packet's size is a multiple of the buffer. The reason for this is if the buffer gets filled on a read it is assumed there is more data; but the same problem happens as before. A 2 byte buffer, for exmaple, gets filled twice on a 4 byte packet, and assumes there is more data. It then blocks because there is nothing left to read. The problem is that the receive function doesn't know when the end of the packet is.

This got me thinking to two possible solutions: I could either have an end-of-packet delimiter or I could read the packet header to find the length and then receive exactly that amount (as I originally suggested).

There's problems with each of these, though. I don't like the idea of using a delimiter, as a user could somehow work that into a packet in an input string from the app and screw it up. It also just seems kinda sloppy to me.

The length header sounds ok, but I'm planning on using protocol buffers - I don't know the format of the data. Is there a length header? How many bytes is it? Would this be something I implement myself? Etc..

What should I do?

解决方案

No - call BeginReceive again from the callback handler, until EndReceive returns 0. Basically, you should keep on receiving asynchronously, assuming you want the fullest benefit of asynchronous IO.

If you look at the MSDN page for Socket.BeginReceive you'll see an example of this. (Admittedly it's not as easy to follow as it might be.)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值