- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
当以 1024 字节的 block 读取数据时,我如何继续从接收大于 1024 字节的消息的套接字中读取数据,直到没有数据为止?我是否应该只使用 BeginReceive 只读取数据包的长度前缀,然后一旦检索到,使用 Receive() (在异步线程中)读取数据包的其余部分?还是有别的办法?
我认为 Jon Skeet 的链接有解决方案,但该代码有一点速度障碍。我使用的代码是:
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();
}
现在这个更正在大多数时候都可以正常工作,但是当数据包的大小是缓冲区的倍数时它会失败。这样做的原因是如果缓冲区在读取时被填满,则假定有更多数据;但是和以前一样发生同样的问题。例如,一个 2 字节的缓冲区在一个 4 字节的数据包上被填充了两次,并假设有更多的数据。然后它会阻塞,因为没有什么可读的了。 问题是接收函数不知道数据包结束的时间。
这让我想到了两种可能的解决方案:我可以使用数据包结束定界符,或者我可以读取数据包 header 以找到长度,然后准确接收该长度(正如我最初建议的那样)。
不过,这些都存在问题。我不喜欢使用定界符的想法,因为用户可能会以某种方式将其处理成来自应用程序的输入字符串中的数据包并将其搞砸。它对我来说也有点草率。
长度 header 听起来不错,但我打算使用 Protocol Buffer - 我不知道数据的格式。有长度标题吗?它有多少字节?这是我自己实现的吗?等等。
我该怎么办?
最佳答案
否 - 从回调处理程序再次调用 BeginReceive
,直到 EndReceive
返回 0。基本上,您应该继续异步接收,假设您想要异步 IO 的最大好处.
如果您查看 Socket.BeginReceive
的 MSDN 页面你会看到一个这样的例子。 (诚然,它并不像它可能的那样容易理解。)
关于C# Begin/EndReceive - 如何读取大数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/582550/
我正在尝试使用 Socket.BeginReceive(...) 和 Socket.EndReceive(...) 作为我的 UDP 数据包接收器客户端。它按预期接收和处理数据包,但是,当我希望取消和
我是编程新手,对异步套接字编程感到困惑。 例如,假设我有两个 BeginSend,一个接一个。第一个发送一百万个字符,第二个仅发送 64 个字符。 由于异步性质,第二个 BeginSend 不会在第一
我一直在查看处理来自 MSMQ 的消息的服务的示例代码。在代码中,在 ReceiveCompletedEventHandler 的开头立即调用 EndReceive() 方法,然后它开始实际处理消息的
当以 1024 字节的 block 读取数据时,我如何继续从接收大于 1024 字节的消息的套接字中读取数据,直到没有数据为止?我是否应该只使用 BeginReceive 只读取数据包的长度前缀,然后
我的 TCP 客户端在接收数据时卡住了。 已建立连接 客户端发送 21 个字节。 (见#5) 客户端上的下一个 BeginReceive 调用永远不会调用回调。当我强制它调用 EndReceive 时
关于 microsoft site您可以找到 ReadCallback(IAsyncResult) 的代码 static void ReadCallback(IAsyncResult ar) {
我正在套接字上进行以下 BeginReceive 调用: m_socket.BeginReceive(m_buffer, 0, m_buffer.Length, SocketFlags.Partial
要从套接字异步接收数据,.Net 支持对称的 BeginReceive/EndReceive 调用。基本上你调用BeginReceive()开始监听并确定数据到达时应调用的回调。在回调中调用 EndR
Socket.BeginReceive/EndReceive 函数的调用顺序是什么? 例如,我两次调用 BeginReceive,一次是为了获取消息长度,第二次是为了获取消息本身。现在的场景是这样的,
我需要接收异步消息。 在所有消息中,前 2 个字节表示下一个字节数组的长度。我的问题是在少数情况下我会收到意外的数据包。 如果我使用 Thread.Sleep(200)这个问题不会发生,或者很少发生。
问题: 当我做这样的事情时: for (int i = 0; i < 100; i++) { SendMessage( sometSocket, i.ToString()); Thre
背景: 我正在编写的应用程序使用异步套接字(使用 BeginSend、EndSend、BeginReceive、EndReceive)在彼此之间发送数据。 IPV4 上的套接字是 TCP,没有套接字标
我正在开发一个 C# 程序,我想在其中与 wifi 模块 ( RN 171 ) 交谈。 在我的 Program.cs 中,当我收到 RabbitMQ 消息时,我直接调用我的 Start 方法。 我从
我无法从文档中看出这两者之间的区别: Socket.EndReceive Method (IAsyncResult, SocketError) Socket.EndReceive Method (IA
我在 Windows 服务中使用异步回调来接收网络上的 UDP 数据广播。 回调使用 UDPClient.EndReceive() 方法来结束挂起的异步接收。在服务 OnStop() 方法期间,我 U
我在 SubscriptionClient 上调用 BeginReceive(),如下所示: client.BeginReceive(new TimeSpan(6, 0, 0), new AsyncC
我正在尝试实现包装器类,它将简单地连接到 TCP 服务器并等待数据。一旦数据从服务器提交 - 我将收到此数据并将其传递给我类(class)的订阅者。 这一切都有效。现在我想添加外部功能以在计时器上“重
我在 Windows 服务中使用 MSMQ。 当服务暂停时,我想关闭 MSMQ 并在服务恢复时重新打开它。 代码如下所示: 开始 _mq.ReceiveCompleted += this.Receiv
这与我上一个问题类似。我正在制作一个简单的 tcp/ip 聊天程序,但在使用 EndReceive Callback 函数时遇到了一些困难。我粘贴了 Microsoft 的实现(见下文),我注意到如果
我正在使用 Service Bus 2.1 For Windows Server,并且我有一种异步接收消息的方法。 我的方法的主体是: var waitTimeout = TimeSpan.FromS
我是一名优秀的程序员,十分优秀!