首先为什么要实行分块传输字符串,一般而言Socket套接字最长发送的字节数为8192字节,如果发送的字节超出了此范围则后续部分会被自动截断,此时将字符串进行分块传输将显得格外重要,分块传输的关键在于封装实现一个字符串切割函数,将特定缓冲区内的字串动态切割成一个个小的子块,当切割结束后会得到该数据块的个数,此时通过套接字将个数发送至服务端此时服务端在依次循环接收数据包直到接收完所有数据包之后在组合并显示即可。

14.3.1 服务端实现

对于服务端而言只需要做两步,首先等待客户端上线,当客户端上线后则服务端会通过recv()接收当前客户端内有多少数据包,当获取到该数据包数量后再以此数量作为循环条件,循环接收数据包并在接收后通过strcat将数据包进行连接,最终合并为一个缓冲区,并输出即可;

#include <WinSock2.h>
#include <Windows.h>
#include <iostream> #pragma comment(lib,"ws2_32.lib") int main(int argc, char* argv[])
{
WSADATA WSAData;
SOCKET sock, msgsock;
struct sockaddr_in ServerAddr; if (WSAStartup(MAKEWORD(2, 0), &WSAData) != SOCKET_ERROR)
{
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(9999);
ServerAddr.sin_addr.s_addr = INADDR_ANY; sock = socket(AF_INET, SOCK_STREAM, 0);
bind(sock, (LPSOCKADDR)&ServerAddr, sizeof(ServerAddr));
listen(sock, 10);
} msgsock = accept(sock, (LPSOCKADDR)0, (int*)0); // 接收需要获取的次数
char recv_count[1024] = { 0 };
recv(msgsock, recv_count, 1024, 0);
std::cout << "收包次数: " << recv_count << std::endl; // 循环收包,并将数据包放入到此变量中
char szBuffer[8192] = { 0 }; for (int x = 0; x < atoi(recv_count); x++)
{
char Split[128] = { 0 };
recv(msgsock, Split, 100, 0); // std::cout << "收到数据包: " << Split << std::endl;
strcat(szBuffer, Split);
} std::cout << "完整数据包: " << szBuffer << std::endl;
closesocket(msgsock);
closesocket(sock);
WSACleanup();
return 0;
}

14.3.2 客户端实现

我们将一段长字符串进行切割每次发送100个字符,该功能的实现首先依赖于Cat函数,该函数通过传入待切割字符串指针,切割偏移以及长度,即可实现分割字符串,如下代码中通过调用Cat(szBuffer, x, 99)切割字符串,这里我们每次剪切100个字符,并将剪切后的字符依次存储到Split[y]这个缓冲区内,接着通过调用strlen()依次计算出当前有多少个100字符行,并在计算结束后首先向服务端发送数据包的数量,当服务端接收到数量后会进入等待模式,此时客户端只需要通过循环的方式发送数据包即可,当然此段代码也存在问题,没有对数据包进行严格的验证,此处读者可自行完善;

#include <WinSock2.h>
#include <Windows.h>
#include <iostream> #pragma comment(lib,"ws2_32.lib") char* Cut(char* buffer, int offset, int length)
{
char Split[100] = { 0 }; // 每100个字符切割一次
memset(Split, 0, 100);
strncpy(Split, buffer + offset, length);
return Split;
} int main(int argc, char* argv[])
{
WSADATA WSAData;
SOCKET sock;
struct sockaddr_in ClientAddr; if (WSAStartup(MAKEWORD(2, 0), &WSAData) != SOCKET_ERROR)
{
ClientAddr.sin_family = AF_INET;
ClientAddr.sin_port = htons(9999);
ClientAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); sock = socket(AF_INET, SOCK_STREAM, 0);
int Ret = connect(sock, (LPSOCKADDR)&ClientAddr, sizeof(ClientAddr));
if (Ret == 0)
{
char szBuffer[8192] = "hello lyshark hello lyshark hello lyshark ";
char Split[100][1024] = { 0 }; // 每次剪切100个字符
for (int x = 0, y = 0; x < strlen(szBuffer); x += 99)
{
char* ref = Cut(szBuffer, x, 99);
strcpy(Split[y], ref);
y += 1;
} // 计算当前有多少个100字符行
int rows = sizeof(Split) / sizeof(Split[0]);
int count = 0;
for (int x = 0; x < rows; x++)
{
if (strlen(Split[x]) != 0)
{
count += 1;
}
} // 将发送数据包次数发送给服务端
std::cout << "发包次数: " << count << std::endl;
char send_count[1024] = { 0 };
sprintf(send_count, "%d", count);
send(sock, send_count, strlen(send_count), 0); // 循环发送数据包
for (int x = 0; x < count; x++)
{
std::cout << "发送数据包: " << Split[x] << std::endl;
send(sock, Split[x], strlen(Split[x]), 0);
}
}
}
closesocket(sock);
WSACleanup();
Sleep(5000);
return 0;
}

运行上述程序片段,读者可看到如下图所示的输出效果,此处只需要分割8个数据包即可完成数据的发送;

14.3 Socket 字符串分块传输的更多相关文章

  1. atitit.二进制数据无损转字符串网络传输

    atitit.二进制数据无损转字符串网络传输 1. gbk的网络传输问题,为什么gbk不能使用来传输二进制数据 1 2. base64 2 3. iso-8859-1  (推荐) 2 4. utf-8 ...

  2. HTTP分块传输

    HTTP分块传输 用途 对于在发送HTTP头部前,无法计算出Content-Length的HTTP请求及回复(例如WEB服务端产生的动态内容),可以使用分块传输,使得不至于等待所有数据产生后,再发送带 ...

  3. 洗礼灵魂,修炼python(86)--全栈项目实战篇(12)—— 利用socket实现文件传输/并发式聊天

    由于本篇博文的项目都很简单,所以本次开个特例,本次解析两个项目,但是都很简单的 项目一:用socket实现文件传输 本项目很简单,作为小项目的预热的,前面刚学完socket,这里马上又利用socket ...

  4. Burpsuit分块传输插件绕WAF原理和技巧(转)

      0x00 原理 给服务器发送payload数据包,使得waf无法识别出payload,当apache,tomcat等web容器能正常解析其内容.如图一所示 0x02  实验环境 本机win10+x ...

  5. HTTP 响应的分块传输

    Transfer-Encoding 响应头用于告诉客户端服务器发送内容的编码格式. 其可选值有: chunked:数据分块发送.此时应缺省 Content-Length 响应头. compress:使 ...

  6. 利用分块传输吊打所有WAF--学习笔记

    在看了bypassword的<在HTTP协议层面绕过WAF>之后,想起了之前做过的一些研究,所以写个简单的短文来补充一下文章里“分块传输”部分没提到的两个技巧. 技巧1 使用注释扰乱分块数 ...

  7. HTTP 笔记与总结(9)分块传输、持久链接 与 反向 ajax(comet / server push / 服务器推技术)

    反向 ajax 又叫 comet / server push / 服务器推技术 应用范围:网页聊天服务器,例如新浪微博在线聊天.google mail 网页聊天 原理:一般而言,HTTP 协议的特点是 ...

  8. java socket 多线程网络传输多个文件

    http://blog.csdn.net/njchenyi/article/details/9072845 java socket 多线程网络传输多个文件 2013-06-10 21:26 3596人 ...

  9. Python Cookbook(第3版)中文版:15.14 传递Unicode字符串给C函数库

    15.14 传递Unicode字符串给C函数库¶ 问题¶ 你要写一个扩展模块,需要将一个Python字符串传递给C的某个库函数,但是这个函数不知道该怎么处理Unicode. 解决方案¶ 这里我们需要考 ...

  10. JAVA之旅(三十二)——JAVA网络请求,IP地址,TCP/UDP通讯协议概述,Socket,UDP传输,多线程UDP聊天应用

    JAVA之旅(三十二)--JAVA网络请求,IP地址,TCP/UDP通讯协议概述,Socket,UDP传输,多线程UDP聊天应用 GUI写到一半电脑系统挂了,也就算了,最多GUI还有一个提示框和实例, ...

随机推荐

  1. vue3.0 学习使用记录

    vue学习 在最近的一次项目中,前端js框架里使用了vue.vue的编程思想比较新颖,用起来也感觉高效便捷.由于个人原因,做完这个项目之后可能就接触不到前端的内容了,所以记录这个项目中对vue的学习和 ...

  2. 2021 年如何学习 Android,一位 5 年中大厂老哥跟你聊聊

    本文首发我的微信公众号:程序员徐公 大家好,我是程序员徐公,加上实习,有五年中大厂经验.今天,我们一起来聊一聊如何自学 Android. 光阴似箭,日月如梭,时间真的过得飞快. 加上实习,从事 And ...

  3. Grafana--双Y轴

    grafana版本:6.5.2 背景:同一面板里想展示各实例与集群在一段时间范围内,平均每秒执行命令数,但是由于数值差异太大,曲线图抖动不明显,实例的更近乎于一条直线,所以设置双Y轴,可更直观的展示线 ...

  4. 网传的Spring大漏洞

    昨天凌晨发了篇关于Spring大漏洞的推文,白天就有不少小伙伴问文章怎么删了. 主要是因为收到朋友提醒说可能发这个会违规(原因可参考:阿里云因发现Log4j2核弹级漏洞但未及时上报,被工信部处罚),所 ...

  5. AtCoder Beginner Contest 242(C~E)

    AB 水题 C - 1111gal password 题意:给出 N(\(2\le N\le 1e6\))求满足以下条件的 \(X\) 的数量,需除以模 (\(998244353\)) $X $ 是 ...

  6. 3.1 《数据库系统概论》SQL概述及数据定义(模式SCHEMA、表TABLE、索引INDEX)

    前言 本篇文章学习书籍:<数据库系统概论>第5版 王珊 萨师煊编著 视频资源来自:数据库系统概论完整版(基础篇+高级篇+新技术篇) 由于 BitHachi 学长已经系统的整理过本书了,我在 ...

  7. vue tabBar导航栏设计实现2-抽取tab-bar

    系列导航 一.vue tabBar导航栏设计实现1-初步设计 二.vue tabBar导航栏设计实现2-抽取tab-bar 三.vue tabBar导航栏设计实现3-进一步抽取tab-item 四.v ...

  8. 处理uniapp(同理小程序)开发中使用rich-text富文本解析,图片未自适应宽度问题(图片显示不全)

    https://www.cnblogs.com/luyaru/p/15538883.html

  9. [转帖]Oracle nvarchar2存储特殊字符乱码问题

    https://www.cnblogs.com/PiscesCanon/p/15157506.html 这个问题研究了一天多,终于搞定了. 起因是业务需要存特殊字符'ø'到varchar2的字段中出现 ...

  10. 【转帖】ESXi 6.x 安装storcli监控raid卡状态

    https://b2b.baidu.com/land?id=744541c6188f7937d6dc97d6fb9142ff10 脚本宝典收集整理的这篇文章主要介绍了ESXi 6.x 安装storcl ...