C# Socket BeginReceive / EndReceive 捕获多条消息

2023-11-29

问题:

当我做这样的事情时:

for (int i = 0; i < 100; i++)
{
    SendMessage( sometSocket, i.ToString());
    Thread.Sleep(250); // works with this, doesn't work without
}

无论是否处于睡眠状态,服务器都会记录单独消息的发送。然而,如果没有睡眠,客户端最终会在单个 OnDataReceived 中接收多条消息,因此客户端将收到如下消息:

0, 1、 2、 34、 5、 678、 9 ....

服务器发送代码:

private void SendMessage(Socket socket, string message)
{
    logger.Info("SendMessage: Preparing to send message:" + message);            

    byte[] byteData = Encoding.ASCII.GetBytes(message);

    if (socket == null) return;
    if (!socket.Connected) return;

    logger.Info("SendMessage: Sending message to non " +
                "null and connected socket with ip:" + socket.RemoteEndPoint);

    // Record this message so unit testing can very this works.

    socket.Send(byteData);
}

客户端接收代码:

private void OnDataReceived(IAsyncResult asyn)
{
    logger.Info("OnDataReceived: Data received.");

    try
    {
        SocketPacket theSockId = (SocketPacket)asyn.AsyncState;
        int iRx = theSockId.Socket.EndReceive(asyn);
        char[] chars = new char[iRx + 1];
        System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder();
        int charLen = d.GetChars(theSockId.DataBuffer, 0, iRx, chars, 0);
        System.String szData = new System.String(chars);

        logger.Info("OnDataReceived: Received message:" + szData);

        InvokeMessageReceived(new SocketMessageEventArgs(szData));

        WaitForData();  // .....  

套接字数据包:

public class SocketPacket
{
    private Socket _socket;
    private readonly int _clientNumber;
    private byte[] _dataBuffer = new byte[1024]; ....

我的预感是这与缓冲区大小有关,或者只是在 OnDataReceived 和 EndReceive 之间我们收到多条消息。

更新:事实证明,当我将 Thread.Sleep 放在 OnDataReceived 的开头时,它会获取每条消息。将我的消息包装在长度前缀和表示结束的字符串中是唯一的解决方案吗?


This is 预期的行为。TCP 套接字表示线性字节流,not一系列明确界定的“数据包”。您不能假设您收到的数据按照发送时的方式进行分块。

请注意,这有two结果:

  1. 两条消息可能会合并到一个回调调用中。 (你注意到了这个。)
  2. 一条消息可能(在任何时候)分成两个单独的回调调用。

你的代码must必须编写来处理这两种情况,否则就会出现错误。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# Socket BeginReceive / EndReceive 捕获多条消息 的相关文章

随机推荐

  • 将 System.ComponentModel.DataAnnotations 与 Entity Framework 4.0 结合使用

    我正在使用 MVC3 并使用 Entity Framework 4 0 实体作为我的模型 到目前为止 就将其用作模型而言 一切都运行良好 所有增删改查操作 页面生成都是开箱即用的 不过 我想知道如何获得与手动生成模型时相同的强大标签和验证信
  • WebLogic 12.2.1 中的最大帖子大小

    我在使用 WebLogic 12 2 1 时遇到问题 从版本 10 3 2 迁移到版本 12 2 1 后 我意识到我可以使用大于 4096 的帖子进行身份验证 这是 WLO 12 1 2 中的新约束 参考 https docs oracle
  • Mybatis ResultMap 是 HashMap

    我似乎找不到一种方法来获取结果地图作为地图 MySQL 是
  • 运行 dev_appserver.py 时如何访问远程数据存储?

    我正在尝试运行一个本地主机 Web 服务器 该服务器可以使用以下命令对远程数据存储进行远程 api 访问 remote api stub method ConfigureRemoteApiForOAuth 我一直在使用以下谷歌文档作为参考
  • Android 设备选择器 - 调试列

    当您使用多个 Android 设备从 Eclipse 进行调试时 您会看到 Android 设备选择器 对话框 您可以选择其中一个来部署应用程序 该对话框有一个 调试 列 该列到底意味着什么 我的一部手机说 是 而另一部则什么也没说 第二部
  • 如何使用和不使用 JavaScript 将数据发布到 CouchDB

    我有一个节目显示一个表单 其中包含从文档填充的字段 我想更改该字段中的值 然后保存更新的文档 我很难找到一个清晰 简洁的示例来说明如何执行此操作 说真的 仅仅完成这个例子就会为很多人带来奇迹 我将省略很多内容以使其简洁 安装 Couchap
  • 更新“订单”列 MySQL?

    更新 订单 列的最佳方法是什么 假设我有一个 id 列从 0 到 9 order 列从 0 到 9 目前 它在数据库中的形式为 0 0 1 1 2 2 等 我的 HTML 页面发布了它想要的新顺序 0 8 1 3 2 6 等 这是完全随机的
  • 根据用户定义的类型创建表

    假设我有一个用户定义的类型 CREATE OR REPLACE TYPE TEST TYPE AS OBJECT f1 varchar2 10 f2 number 5 现在 我想创建一个表来保存这些类型 我可以执行以下操作 create t
  • 通过网络 ODBC 访问 *.mdb

    我有一个关于带有 mdb 的 ODBC 如何工作的一般性问题 根据我的理解 如果我错了 请纠正我 无论我是否使用odbc 当访问存储在另一台计算机 即NAS 上的MS Access数据库 mdb 时 我的计算机首先需要在对其执行任何操作之前
  • XCode:设置多个 UITableView 列

    我还没有找到一个好的答案 我一定很笨 但是 我正在尝试在每行中设置一个带有图像和标签的表格视图 该图像将是一个指示图像 新的 正在进行的 已停止的 已完成的等 标签将是一个特定的问题名称 我可以正常设置一列的表视图 但我找不到任何设置表列数
  • MongoDB - 根据嵌套数组的字段值更新数组对象中的字段

    我正在尝试更新对象数组内的字段 其中嵌套数组中的字段等于一个值 我的目标是设定picture字段一个新的 url 其中value领域在valueList is oldRed 产品架构 variations id 1 picture http
  • 为输出文件指定日期和时间

    我正在研究ffmpeg屏幕捕获 我不希望它在启动时开始录制 所以我需要给输出视频文件一个每次开始录制时都不同的名称 我确实发现这个问题非常接近我需要的 所以我结束了在批处理文件中使用以下命令 echo off For f tokens 2
  • 画布仅在循环结束后重绘

    我在画布上循环绘图时遇到问题 我想要实现的是 在每个循环中 脚本等待几毫秒 然后在画布上绘制 用户实际上可以看到更改 然后重复循环 相反 它所做的是用户无法看到更改 直到 for 循环结束 但我发现 如果我显示一个警报窗口并且脚本等待用户响
  • Azure Web App 部署失败,无法读取未定义的属性“updateStartupCommandAndRuntimeStack”

    尝试将 dotnet core 5 应用程序从 Azure Devops 部署到 Azure Linux Web 应用程序 构建工作正常 但部署步骤总是失败并显示此消息 给出了一些上下文 2021 11 09T09 53 24 617247
  • 错误:找不到符号方法 findViewById(int)

    我在我的小应用程序中遇到了 WebView 问题 我的布局中有相关的 webview 和正确的信息 并且我有直接来自 Android 开发人员站点的示例代码 但它不适合我 错误围绕 findViewById R id webview met
  • 如何计算 TTF 字体中两个字形之间的间距?

    这是一个定义了a的图字体水平字形度量的几个术语 假设我有一句话 Foo 酒吧巴兹 如何获取单词 Foo 和 bar 之间的间距大小 以像素为单位 我想我总结一下 Foo 中 o 字素中的空白右侧填充 从advance the bearing
  • 操作对象文字:按特定顺序添加属性

    我正在开发一个在线创建 Nassi Shneiderman 图的工具 每个图的模型只是一个对象文字 存储具有无限可能的子项的所有内容 this then results in a view populated like the follow
  • 幂查询 M IN 运算符

    相当于 SQL 的什么INPower BI 的运算符 就像子句中一样 where Column1 IN Value1 Value2 Value3 我正在寻找 M 解决方案 不是 DAX 您可以使用List Contains功能 例如 Tab
  • Guice 在实例化对象后调用 init 方法

    是否可以告诉 Guice 在之后调用某个方法 即 init 实例化给定类型的对象 我在 EJB 3 和 Spring 中寻找类似于 PostConstruct 注释的功能 您只需添加 Inject注释到你的init 方法 实例化对象后它将自
  • C# Socket BeginReceive / EndReceive 捕获多条消息

    问题 当我做这样的事情时 for int i 0 i lt 100 i SendMessage sometSocket i ToString Thread Sleep 250 works with this doesn t work wit