如何提取消息的长度信息并从 TCP 字节流中仅提取那么多消息?

2024-02-07

我正在尝试通过 C++ 中的 Socket 发送消息。我已经阅读了许多与此相关的堆栈溢出问题,但仍然无法弄清楚它是如何工作的。假设我正在向本地主机服务器发送以下字符(M、a、r、t、i、n),人们建议您可以使用 4 个字节作为长度(即 32 位,以便它可以处理消息)至 4GB 长度)。

我在客户端做了同样的事情,但仍然不知道如何在服务器端弄清楚这个事情,我是否只想接收开始 3 个字节(M,a,r)或最后 3 个字节(t,i,n)我的数据。

我正在发布我的代码,请主要在服务器端帮助我,如果能写几行与代码相关的代码,我将不胜感激。

           Client side code
std::vector<char> userbuffer(20);
std::cout<<"\nclient:"<<std::endl;
    char* p = userbuffer.data();
    *p = 'M';
            ++p; *p = 'a';
            ++p; *p = 'r';
            ++p; *p = 't';
            ++p; *p = 'i'; 
            ++p; *p = 'n';
            size_t length = strlen(userbuffer.data());
    uint32_t nlength = htonl(length);
            //line containg message length information
           int header_info = send(socketFD, (char*)&nlength, 4, 0); 
           // Data bytes send to the server
    int bytes_sent = send(socketFD, userbuffer.data(), length, 0);

    if(bytes_sent == SOCKET_ERROR){ //some errror handling}





 Server Side Code
 char receivebuffer[MAX_DATA] = { '\0' };
 int bytesReceivedFromClientMsg = 1;
 int length_bytes = 0;
 uint32_t length, nlength;
 //code to check length if we have received whole data length
 while(length_bytes < 4){
 int read = recv(clientSocket, ((char*)&nlength)+length_bytes, (4-length_bytes), 0);
 if (read == -1) { //error handling}
 length_bytes += read;}
// Most painfull section to understand.
// I implemented this code from some ideas on internet 
//but still cant find how its extracting length and what i am reading :(
       while(bytesReceivedFromClientMsg > 0){
    int msgheader = recv(clientSocket,(char*)&nlength,6, 0);
    length = ntohl(nlength);//leng value here is in severel thousand size
    char *receivebuffer = new char(length+1);
        bytesReceivedFromClientMsg = recv(clientSocket, receivebuffer, msgheader, 0);
    receivebuffer[length] = 0 ;
    std::cout<<"msg header is :"<<msgheader<<std::endl;
    std::cout<<"msg data is :"<<bytesReceivedFromClientMsg<<std::endl;

        if(bytesReceivedFromClientMsg == SOCKET_ERROR){//some error handling}

您需要为您的网络协议进行设计。有些协议(例如 SMTP)是类似文本的协议。您必须读取字符,直到找到终止字符,例如类似文本协议中的换行符。

使用基于消息的协议,您有更好的机会获得高性能协议。您定义一个标头(在代码中使用但未定义)。在标头中,您可以放置​​有关下一条消息的长度以及可能的类型的信息。然后将标头发送到消息正文前面。在你的例子中,身体是“马丁”。

接收方的状态为“已收到标头”。当未完整接收到标头(或根本没有收到任何标头)时,它将使用标头的大小作为块大小。它将 chunksize 字节接收到 header 变量中。当标头接收完成时,接收器将块大小设置为标头中设置的大小,并将如此多的字节接收到有效负载缓冲区。完成后,状态“收到标头”再次为假。

int receive(socket sock, char * buffer, int chunk_size)
{
    int offset = 0;

    while (chunk_size > 0)
    {
        // add select() here when you have a non-blocking socket.
        int n = recv(sock, buffer+offset, chunk_size);
        // TODO: error handling
        offset += n;
        chunk_size -= n;
    }

    // return amount of received bytes
    return offset;
}

void do_receive(void)
{
    struct {
        int size;
        // other message information
    } header;

    while (true)
    {
        receive(sock, &header, sizeof(header);
        receive(sock, buffer, header.size);
        process_message(buffer, header.size);
    }
}

上面的代码不会通过任何编译器。但它显示了这个想法..

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

如何提取消息的长度信息并从 TCP 字节流中仅提取那么多消息? 的相关文章

  • 如何在 ASP.NET MVC 中将 XML 文件发送到客户端

    在 ASP NET MVC 中 我有一个数据库表 我想在某个视图页面上有一个按钮 如果某个用户单击该按钮 我的应用程序将生成包含数据库中所有行的 XML 文件 然后 应将包含 XML 的文件发送到客户端 以便用户看到下载弹出窗口 同样 我希
  • 为什么 TCP 段中的 SYN 或 FIN 位会占用序列号空间中​​的一个字节?

    我试图理解这种设计背后的基本原理 我浏览了一些 RFC 但没有发现任何明显的东西 这并不是特别微妙 这样 SYN 和 FIN 位本身就可以被确认 因此如果丢失则可以重新发送 例如 如果连接关闭而没有发送更多数据 那么如果 FIN 没有发送任
  • strtok() 使用安全吗[重复]

    这个问题在这里已经有答案了 我读到了很多负面的东西strtok 有人说它已经过时 有人说它不是线程安全的 等等 那么真相是什么 我可以使用吗strtok 它是线程安全的吗 Note 我正在使用 Visual C 您可以使用它 它是标准库的一
  • C# 异步任务比同步慢

    你知道为什么同步斐波那契方法比异步 等待更快并且比异步任务更快吗 我在每个项目方法上都使用了异步 所以主要是这是一个非常糟糕的方法 Code static int FibonacciSync int number if number 0 r
  • 信号与信号2

    我的应用程序可能会受益于使用 boost 的信号库之一而不是本土解决方案 该应用程序是多线程的 但执行信号处理的部分是单线程的 如果多线程不是问题 是否有任何理由更喜欢 Boost Signals2 而不是 Boost Signal Boo
  • 对 ExecuteNonQuery() 的单次调用是原子的

    对 ExecuteNonQuery 的单次调用是否是原子的 或者如果单个 DbCommand 中有多个 sql 语句 那么使用事务是否有意义 请参阅我的示例以进行说明 using var ts new TransactionScope us
  • 如何通过 libwebsocket 发送异步数据?

    我正在将 Warmcat 的 libwebsocket C 库用于小型 Websocket 服务器 我已经启动并运行了这些示例 并且可以发送数据以响应从 websocket 接收数据 例如回显发送的反向字节 但是 我无法弄清楚如何在不使用
  • 预编译头和 Visual Studio

    有没有办法设置 Visual Studio 解决方案参数 以便它只创建预编译头而不构建整个解决方案 具体来说 它是一个巨大的 C 解决方案 本身有许多项目 谢谢 仅选择 pch 创建者源文件 通常是 stdafx cpp 然后编译该文件 C
  • 选择initializer_list迭代器定义

    Why std initializer list
  • 从内存流播放视频文件

    只是好奇看看这是否可能 我有一个 Windows 应用程序 它从我的电脑上的 avi 文件读取所有字节 然后将其存储在 byte 中 现在我的内存中有 avi 文件 我想直接从内存将其加载到某种视频播放器控件中 我尝试过使用 wmplaye
  • 检测反射 DLL 注入

    在过去的几年中 恶意软件 以及一些渗透测试工具 如 Metasploit 的 meterpreter 负载 已经开始使用反射 DLL 注入 PDF http www harmonysecurity com files HS P005 Ref
  • 模板与非模板类,跨编译器的不同行为

    我在一些应用程序中使用编译时计数器 它确实很有用 昨天我想用 gcc 编译一个程序 我之前使用的是 msvc 并且计数器的行为在模板类中发生了变化 它在模板类中不再工作 过于简化的代码 Maximum value the counter c
  • 查找方法不适用于 EF6.1 模拟

    我已经使用这些 msdn 指南设置了模拟 使用模拟框架进行测试 EF6 及以上 http msdn microsoft com en us data dn314429 var bsAc db BusAcnts FirstOrDefault
  • linq where 子句和 count 导致 null 异常

    除非 p School SchoolName 结果为 null 否则下面的代码将起作用 在这种情况下 它会导致 NullReferenceException if ExistingUsers Where p gt p StudentID i
  • Windows 上本机 C++ 应用程序中的自动死代码检测?

    背景 我有一个用原生 C 编写的应用程序 花了几年的时间 大约有 60 KLOC 有很多函数和类已经死了 可能有 10 15 就像下面提出的类似的基于 Unix 的问题 我们最近开始对所有新代码进行单元测试 并尽可能将其应用于修改后的代码
  • 使用 cmake 将两种解决方案合二为一

    我有两个单独的 Visual Studio 2013 解决方案 我想将它们迁移到一个解决方案中 因为第一个解决方案 使用 Qt 充当第二个解决方案的 GUI 最后 我希望有一个结构如下的单一解决方案 Solution All Build P
  • 使用C标准数学库精确计算标准正态分布的CDF

    标准 C 数学库不提供计算标准正态分布 CDF 的函数 normcdf 然而 它确实提供了密切相关的函数 误差函数 erf 和互补误差函数 erfc 计算 CDF 的最快方法通常是通过误差函数 使用预定义常量 M SQRT1 2 来表示 d
  • 强制函数调用的顺序?

    假设我有一个抽象基类 并且我想要一个必须由派生类实现的纯虚方法 但我想确保派生方法以特定顺序调用函数 我可以做什么来强制执行它 I E base class virtual void doABC 0 virtual void A 0 vir
  • 在 C# 中使用自定义千位分隔符

    在显示字符串时 我尝试不使用 字符作为千位分隔符 而是使用空格 我想我需要定义一种自定义文化 但我似乎做得不对 有什么指点吗 例如 将 1000000 显示为 1 000 000 而不是 1 000 000 no String Replac
  • 在 LP2844Z(Zebra 打印机)上的收据中包含 PNG [重复]

    这个问题在这里已经有答案了 我正在致力于创建一个基于 HTML5 画布的签名 绘图框 目前我们在服务器上将画布保存为PNG 但可以轻松地将base64字符串保存在数据库中 现在的问题是我们如何在打印的收据上添加签名 目前我们使用 GF 字段

随机推荐

  • 在特定日期重复 UILocalNotification

    我需要设置 UILocalNotification 我只需要从 DatePicker 获取小时和分钟 并且需要设置特定日期 比如 星期一 并每周一重复一次 我对此有两个问题 第一 是否可以在日期选择器的日期部分仅显示 日期名称 例如 星期日
  • JAX-RS (Resteasy 3.5.0.Final) + Wildfly 12 + Java 9 + maven = 404 未找到,但 JAX-RS (Resteasy 3.5.0.Final) + Wildfly 12 + Java 8 + ma

    我有一个简单的 Hello World 示例 JAX RS 项目 真的很简单又愚蠢 只是最小的配置 我打算在将来增强它 想象一下这样的事情 https robferguson org blog 2016 12 02 getting star
  • 在 django 中运行测试时设置 liveserver 端口

    我正在使用 django 作为 web 应用程序 并使用 docker 来部署它 我需要在带有硒的容器中测试它 我正在使用硒网格进行测试 为了与 docker 上的 liveserver 连接 我需要转发特定端口 但据我在 django 文
  • 添加特定 unicode 表情时 Discord.js message.react 失败

    昨天我开始使用discord js 的指南编写一个机器人 The core https github com discordjs guide tree master code samples command handling file se
  • 多个 id 的更新语句

    我有 3 个表 我需要通过计算其他两个表的数据来更新第三个表的列 update table3 set column3 select t2 column3 t1 column3 from table2 t2 with nolock join
  • 如何迭代 WeakMap?

    JavaScriptWeakMap https developer mozilla org en US docs Web JavaScript Reference Global Objects WeakMap不允许您通过设计获取密钥 长度或
  • 如何将 IEEE-754 格式整数输出为浮点数

    我有一个无符号长整数值 它表示使用 IEEE 754 格式的浮点数 在 C 中将其打印为浮点数的最快方法是什么 我知道一种方法 但我想知道 C 中是否有一个更好的方便实用程序 我所知道的方式的例子是 union unsigned long
  • 使用数据绑定和 MVVM 处理 onClick 事件

    我想设置一个onClickListener on an ImageView using Databinding并控制它ViewModel MVVM 在 xml 布局中我实现的所有内容Databinding作品 但 onClick 事件不起作
  • 在返回 observable 之前操作数据

    我对 Angular 2 和 Observables 的概念还很陌生 然而 对于经验丰富的专家来说 我想要实现的目标应该相当简单 所以 我有一个组件 其中有subscribed来自服务的可观察值 出于测试目的 我一直在使用数据数组来使我的组
  • 无法通过 Style 设置列表框的 GroupStyle?

    我正在尝试创建一个样式来为我的 ListBox 控件设置 GroupStyle 属性 但是我收到编译时错误 The Property Setter GroupStyle cannot be set because it does not h
  • 滑动侧边栏菜单 IOS 8 Swift [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 有没有办法在 IOS Swift 中实现幻灯片侧边栏菜单 如 Facebook 应用程序 而不需要任何第三方库 我寻找解决方案 但我只
  • 一个好的(最好是免费的).Net 应用程序安装程序?

    我有一个使用 Sql Express 的 Net C 应用程序 开发已完成 现在我必须选择一些安装程序来部署我的应用程序 我尝试过 Microsoft Visual Studio 发布向导 但我又爱又恨它 我喜欢它 因为它可以检测客户端计算
  • Django 上的 memcache 不工作

    我有一个竞争条件Celery 受此启发 http ask github io celery cookbook tasks html ensuring a task is only execulated one at a time http
  • mysql 查询:按日期显示所有付款的摘要和发票总数

    I want this kind of result 从这些表中 我什至不知道如何用 php 来做到这一点 我什至尝试按日期加入付款和发票表 但没有成功 这是一个购买系统 此查询将按日期显示所有付款的摘要和发票总数 我想到了一个解决方案 首
  • 在Matlab中确定距海岸线的距离

    在 MATLAB 中 我有一组代表美国位置的纬度和经度对 我需要确定到最近海岸线的距离 我认为 MATLAB 有一个内置的美国经纬度数据库 我如何访问并使用它 关于如何有效确定距离还有什么建议吗 Update 后续问题 使用 meshm 时
  • 如何排除 Azure 数据工厂中复制数据活动中的行?

    我已经构建了一个具有复制数据活动的管道 该活动从Azure Data Lake并将其输出到Azure Blob Storage 在输出中 我可以看到我的某些行没有数据 我想将它们从副本中排除 在以下示例中 第二行没有有用的数据 Tenant
  • 使用“属性路由”时出现“无法找到类型或命名空间名称‘路由’”

    只是试图将一些代码从一个工作项目拼接到另一个工作项目 from 项目在您嵌入的位置使用 属性路由 Route Web API 控制器模块中的指令指示什么 HTTP 消息应路由到什么服务例程 在 from 项目中工作正常 但在 to 项目中我
  • Intellij IDEA 中的快速文档和自动弹出文档有什么区别?

    在我的 Intellij IDEA Ultimate 2017 1 中 我发现两个类似的选项 显示有关鼠标移动的快速文档 自动弹出文档 让我们本地化它们 文件 设置 编辑器 常规 常规 显示有关鼠标移动的快速文档 我看到在查看内联文档 ht
  • JavaFX 导出和 VM 参数

    我遇到的问题是无法导出 JavaFX 应用程序 我可以使用 VM 参数 IDE 内部和外部 运行它 但这远非最佳 我想要一个简单的 点击打开 体验 错误 缺少 JavaFX 运行时组件 并且需要运行该应用程序 我知道这个问题可以通过 vm
  • 如何提取消息的长度信息并从 TCP 字节流中仅提取那么多消息?

    我正在尝试通过 C 中的 Socket 发送消息 我已经阅读了许多与此相关的堆栈溢出问题 但仍然无法弄清楚它是如何工作的 假设我正在向本地主机服务器发送以下字符 M a r t i n 人们建议您可以使用 4 个字节作为长度 即 32 位