概述
c++实现socket以json格式传输图片
整体参考https://blog.csdn.net/weixin_42755375/article/details/81590967
细节1参考 https://blog.csdn.net/weixin_42731241/article/details/81589589
细节2参考 https://www.cnblogs.com/yuqiao/p/5786427.html
一、主要任务:
1、C++实现socket通信
2、socket传输数据要封装成json格式
3、json传输字符串
4、json传输图片
二、大致流程:
客户端读取图片,经过Base64编码,转成字符串的形式,保存在json中,通过socket传到服务端,然后Base64解码,再转换成图片
三、客户端函数细节
前言—什么是socket(套接字)?
socket是使用标准Unix文件描述符(file descriptor)和其它程序通讯的方式
利用系统调用socket(),它返回套接字描述符(socket descriptor),然后再通过它来进行send()和recv()调用。
1.strcpy函数
C++的strcpy()用于字符串复制,用法是传入2个字符数组指针来执行,如strcpy(a,b)是将b指向的字符串复制到a指向的空间中。
详细用法参考
2、fread和fwrite函数
函数功能:用来读取一个数据块
一般调用形式:
fread(buffer,size,count,fp)
fwrite(buffer,size,count,fp)
详细用法参考
3、base64_encode和base64_decode
base64_encode(const char *bytes_to_encode, unsigned int in_len)
返回string
bytes_to_encode—需要编码的数据集
in_len—元素的个数
4、函数1、2、3连起来去理解把图片打包成json对象的过程
std::string chFileIn1 = "E:\"+num+".jpg";
strcpy(chFileIn3, chFileIn1.c_str());
fIn1 = fopen(chFileIn3, "rb");
//fread()读取成功返回值为实际读回的数据个数(单位为Byte)
nRead1 = fread(chBuf1, sizeof(char), 3888888, fIn1);
//读取的内容做base64编码,返回string
//要编码的部分是chBuf1,编码元素的个数是nRead1
string imgBase64_1 = base64_encode(chBuf1, nRead1);
//封装进json
json data1;
data1["imgA"] = imgBase64_1;
fclose(fIn1);
5、socket函数
SOCKET sclient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
winsock库里的函数,创建一个套接字,采用tcp连接
6、inet_addr函数
作用是IP地址格式转换
unsigned long ip = inet_addr("127.0.0.1"); printf("%ldn", ip); >>>1677343
参考
7、send函数—TCP类型的数据发送
int send(int sockfd, const void *msg, int len, int flags)
sockfd – 已建立好连接的socket。
msg – 待发送数据的缓冲区。
len – 待发送数据的字节长度。
flags – 一般情况下置为0。
8、recv函数—TCP类型的数据接收
int recv(int sockfd, void *buf, int len, unsigned int flags)
sockefd – 接收端套接字描述符(非监听描述符);
buf – 接收缓冲区的基地址;
len – 以字节计算的接收缓冲区长度;
flags – 一般情况下置为0。
这两个函数用于流式套接字或者数据报套接字的通讯。
9、函数5、6、7、8连起来理解
OCKET sclient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
//imgBase64_1就是4中解释的最终封装后的json
data1["imgA"] = imgBase64_1;
std::string s = data1.dump();
const char * sendData;
sendData = s.c_str();
send(sclient, sendData, strlen(sendData), 0);
10、connect()程序
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
sockfd是系统调用socket()返回的套接字文件描述符
serv_addr是保存着目的地端口和ip地址的数据结构struct socket
addelen设置为sizeof(struct sockaddr)
参考1
参考2
作用就是通过用户告诉的端口连接到目的IP
客户端的connect函数和服务端的accept函数是一对好基友,如果客户端没有去connect,那么服务器端的accept会一直等待
四、服务端函数细节
1、bind函数
作用是将套接字和机器上的一定的端口关联起来
int bind(int sockfd, struct sockaddr *my_addr, int addrlen);
sockfd 是调用 socket 返回的文件描述符。my_addr 是指向数据结构 struct sockaddr 的指针,它保存你的地址(即端口和 IP 地址) 信息。 addrlen 设置为 sizeof(struct sockaddr)。
2、listen函数
int listen(int sockfd, int backlog);
sockfd 是调用 socket() 返回的套接字文件描述符。backlog 是在进入 队列中允许的连接数目。
进入的连接是在队列中一直等待直 到你接受 (accept() )连接。它们的数目限制于队列的允许。 大多数系统的允许数目是20,你也可以设置为5到10。
3、accept函数
int accept(int sockfd, void *addr, int *addrlen);
addr 是个指 向局部的数据结构 sockaddr_in 的指针。这是要求接入的信息所要去的地 方(你可以测定那个地址在那个端口呼叫你)。
五、工程代码
1、免费 https://blog.csdn.net/weixin_42755375/article/details/81590967
2、收积分 https://download.csdn.net/download/weixin_42755375/10597950?utm_source=bbsseo
两个代码是同一个人写的,是一模一样的,
只不过一个免费,需要自己稍微整理;一个收积分,可以直接下载整个工程
六、bug解决
1、VS 2017新建项目编译时出现 找不到 Windows SDK 版本10.0.请安装所需的版本的 Windows SDK 或者在项目属性页的问题解决方案
解决:右键项目解决方案—重定解决方案目标—重定向项目—确定
参考1
2、无法找到源文件 winsock.h,stdio.h
其实问题2和问题1是同一个原因
解决办法:
控制面板—程序—选择更改visual studio 2017
进入visual studio installer,找到“使用C++的桌面开发”,勾掉右上角的勾选,然后再重新勾选上,有更新的话可以先更新
参考1
3、error C4996: ‘strcpy’: This function or variable may be unsafe. Consider using strcpy_s instead.
出现这个错误时,是因为strcpy函数不安全造成的溢出
解决办法:右键项目—属性—C/C++—预处理器—预处理器定义
编辑,在里面加入一段代码:
_CRT_SECURE_NO_WARNINGS
点击确定
参考2
4、VS2017中C4996 ‘inet_addr’: Use inet_pton() or InetPton() instead or define _WINS
在VS2013以后的版本,增加了inet_pton()/InetPton()之类的新函数,用于IP地址在“点分十进制”和“二进制整数”之间转换,并且能够处理ipv4和ipv6.
而inet_addr是老函数
其实in_addr与inet_pton的联系就像是strcpy与strcoy_s的联系.微软强迫别人用她的新函数
解决办法1
1.用socket的新函数代替程序出现的所有老函数,不光是in_addr.还有gethostbyname.学习成本太高.
2.在项目属性里设置,告诉编译器,我就用老函数,让她不要报错了.
右键项目—属性—C/C++—常规—SDL检查,把是改为否
参考3
参考4
5、error C4996: ‘inet_ntoa’: Use inet_ntop() or InetNtop() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings
产生原因和解决办法参见问题4
最后
以上就是彪壮豌豆为你收集整理的c++实现socket以json格式传输图片c++实现socket以json格式传输图片的全部内容,希望文章能够帮你解决c++实现socket以json格式传输图片c++实现socket以json格式传输图片所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复