14.3 Socket 字符串分块传输
首先为什么要实行分块传输字符串,一般而言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 字符串分块传输的更多相关文章
- atitit.二进制数据无损转字符串网络传输
atitit.二进制数据无损转字符串网络传输 1. gbk的网络传输问题,为什么gbk不能使用来传输二进制数据 1 2. base64 2 3. iso-8859-1 (推荐) 2 4. utf-8 ...
- HTTP分块传输
HTTP分块传输 用途 对于在发送HTTP头部前,无法计算出Content-Length的HTTP请求及回复(例如WEB服务端产生的动态内容),可以使用分块传输,使得不至于等待所有数据产生后,再发送带 ...
- 洗礼灵魂,修炼python(86)--全栈项目实战篇(12)—— 利用socket实现文件传输/并发式聊天
由于本篇博文的项目都很简单,所以本次开个特例,本次解析两个项目,但是都很简单的 项目一:用socket实现文件传输 本项目很简单,作为小项目的预热的,前面刚学完socket,这里马上又利用socket ...
- Burpsuit分块传输插件绕WAF原理和技巧(转)
0x00 原理 给服务器发送payload数据包,使得waf无法识别出payload,当apache,tomcat等web容器能正常解析其内容.如图一所示 0x02 实验环境 本机win10+x ...
- HTTP 响应的分块传输
Transfer-Encoding 响应头用于告诉客户端服务器发送内容的编码格式. 其可选值有: chunked:数据分块发送.此时应缺省 Content-Length 响应头. compress:使 ...
- 利用分块传输吊打所有WAF--学习笔记
在看了bypassword的<在HTTP协议层面绕过WAF>之后,想起了之前做过的一些研究,所以写个简单的短文来补充一下文章里“分块传输”部分没提到的两个技巧. 技巧1 使用注释扰乱分块数 ...
- HTTP 笔记与总结(9)分块传输、持久链接 与 反向 ajax(comet / server push / 服务器推技术)
反向 ajax 又叫 comet / server push / 服务器推技术 应用范围:网页聊天服务器,例如新浪微博在线聊天.google mail 网页聊天 原理:一般而言,HTTP 协议的特点是 ...
- java socket 多线程网络传输多个文件
http://blog.csdn.net/njchenyi/article/details/9072845 java socket 多线程网络传输多个文件 2013-06-10 21:26 3596人 ...
- Python Cookbook(第3版)中文版:15.14 传递Unicode字符串给C函数库
15.14 传递Unicode字符串给C函数库¶ 问题¶ 你要写一个扩展模块,需要将一个Python字符串传递给C的某个库函数,但是这个函数不知道该怎么处理Unicode. 解决方案¶ 这里我们需要考 ...
- JAVA之旅(三十二)——JAVA网络请求,IP地址,TCP/UDP通讯协议概述,Socket,UDP传输,多线程UDP聊天应用
JAVA之旅(三十二)--JAVA网络请求,IP地址,TCP/UDP通讯协议概述,Socket,UDP传输,多线程UDP聊天应用 GUI写到一半电脑系统挂了,也就算了,最多GUI还有一个提示框和实例, ...
随机推荐
- 围绕ChatGPT,做了点小事,赚了点小钱
大家好,我是章北海mlpy 作为 ChatGPT 日活用户,分享一下经验和用它做的一些小事吧. 经验不敢当,只是觉得大家把ChatGPT当成了高大上的黑科技,其实它就是个工具,就像你买了个新手机一样, ...
- ZK--简介,部署
官网:https://zookeeper.apache.org/ 本文zk版本:3.7.0 一.简介 ZooKeeper 是一个高可用的分布式数据管理与系统协调软件,它可以为分布式应用提供状态同步.配 ...
- 阿里云 AI 编辑部获 CCBN 创新奖,揭秘传媒行业解决方案背后的黑科技
5 月 27 日,CCBN(第二十八届中国国际广播电视信息网络展览会)在北京隆重召开,在本次的 "CCBN 年度创新奖" 评选中,阿里云视频云凭借AI 编辑部的传媒行业专业解决方案 ...
- sipp3.6带媒体测试方案
概述 SIP压测工具sipp,免费,开源,功能足够强大,配置灵活,优点多. 本文档介绍sipp工具如何带媒体测试,并介绍如何制作可用的媒体文件(G729和PCMA). 环境 centos7.9 fre ...
- Dubbo入门1:Spirngboot+Dubbo2.6.0整合
整合springboot+dubbo2.6.0 demo 本文简要说明了springboot和dubbo整合的配置文件的写法 目录结构 整体目录 如下图所示:整体项目是一个父子工程,common作为一 ...
- SV OOP-2
静态变量 继承性(Inheritance) 抽象类和虚方法virtual methods 多态(Ploymorphism) 通过基类的变量可以使用子类的对象 基类中定义的virtual functio ...
- AHB Matrix
常用的AHB Bus结构 AHB Matrix AHB Bus Matrix,即总线矩阵,其实际上就是一个互连(Interconnect).用于连接满足该总线协议的外设,包括Master和Slave. ...
- 一个容易弄错的.textContent和text()问题
最近在写一些前端页面,遇到需要通过点击事件获取被点击对象的文本内容,正确代码如下: <!DOCTYPE html> <html lang="en"> < ...
- Oracle数据库如何解决创建用户名开头必须要C##问题?
1.问题 我们在创建用户,概要文件等时,由于使用的是容器数据库,其文件名必须以C##开头. 我们在学习过程中暂时不需要对齐进行区分,所以如何修改这个设定呢? 2.解决 参考链接如何解决创建用户名开头必 ...
- C++17 解构绑定
在python中,加入我们有一个函数返回了两个数值,如: def getData(x, y): return x,y 那么我们在使用这个函数时只需要使用两个新变量去接收函数返回值就可以: a,b = ...