IOS 基于TCP的socket通信详解

IOS 基于TCP的socket通信详解,第1张

最近在整理通信层相关知识,这篇文章是边整理边写的,有些地方可能不够准确,还请各位路过的大牛专家指出来。这次整理的socket通信是基于TCP的,实现方式是GCD形式,以下记录的都是些理论知识,方便自己回忆。

1、socket通信原理:现网络上有很多socket开园框架文件,基本上能满足简单网络通信,但如过你的项目需要成熟的网络通信,还需要自 己对socket好好研究完善下。socket通信分为server端和client端,开发过程中分别对应着服务器和客户端。当连接上服务器 后,socket就会启动一个while或for无限循环,不断的异步监听socket动静,看是否有read或者write动作,直到出错或者主动结 束。

socket通信传输的都是字节流,传输时没有包的概念的。至于我们经常说的包的概念,是我们制定了一定的规则形成的。常用规则有两种,一 种是制定特定的分隔符(delimiter)来分割每个包,此时必须保证每条信息体中不包含该分隔符。第二种是指定每条消息体的长度,比如,在每条消息体 之前插入一个4字节长度的无符号整形来表明后面的消息体长度(一般包体长度限制在8k大小内,遇到消息体过大的信息时,一般采用分包发送和拼包解析)。其 中第二种方式更常见一些。

基于TCP链接的socket通信中,经常会涉及粘包、分包、解包的问题,一下久这问题简单说一下。

粘包:使用TCP长连接就会引入粘包的问题,粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接 着前一包数据 的尾。粘包可能由发送方造成,也可能由接收方造成。TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一包数据,造成多个数据包的粘连。如果 接收进程不及时接收数据,已收到的数据就放在系统接收缓冲区,用户进程读取数据时就可能同时读到多个数据包。
粘包一般的解决办法是制定通讯协议,由协议来规定如何分包解包。

分包:常用分包的逻辑是先发一个长度,然后紧接着是数据包内容,这样就可以把每个包分开。

解包:由于我们应用层数据包既可以传命令也可以传数据,因而针对每个包我们进行解包,分出命令和数据分别处理,因而每个Socket服务对象都需要解包。解包过程中,才会出现我们常见的包头、信息体长度、信息体。

粘包、分包、解包解决方案:东家DZH:采用的是用一个足够大(500*1024)的接受缓存pRecvBuf去读区socket(recv()),然后使用君子协定让数据报的开头都是一个标准的包头信息,包头信息中包含着本包的包体长度,利用这个包体长度曲读取本包数据包体。读完后,如果该数据包还有未读数据,则重复上诉解包 *** 作。直到完成。

东家EM:每次收到数据报时,先读取前4个字节转为无符号整形作为本消息包的长度length,然后一直重socket中read,直到读取length长度为之。这样可以解决分包发送问题,也可以解决粘包问题。

在开发程序的时候 使用易语言的 服务端 与 客户端 控件时 ,一般不直接使用发送数据功能。

因为网络存在丢包的可能,所以易语言的服务端会自动的重发刚刚丢失的包,直到完全结束。

有很多新手朋友在使用易语言传送文件的老出现这个问题。

估计你的这个问题也是一样的原因照成的,丢包!

最简单有效的解决办法:

封装一个发包的方法,我这里已服务端给客户端发送消息举例,到时候你还需要同样在客户端上写相同的代码。

-------------------------------------------

版本 2

程序集 窗口程序集1

程序集变量 temp数据包尾部, 文本型

子程序 __启动窗口_创建完毕

temp数据包尾部 = “{结尾[over]}”

子程序 封装的发送方法

参数 客户IP, 文本型

参数 data, 字节集

服务器1发送数据 (客户IP, data + 到字节集 (temp数据包尾部), )

子程序 _服务器1_数据到达

接收到的数据进行处理 (服务器1取回数据 ())

子程序 接收到的数据进行处理

参数 data, 字节集

局部变量 oldData, 字节集, 静态, , 注意,这是一个静态的变量,如果理解不到静态的意思就请使用全局变量

oldData = oldData + oldData

' 判断如果 该数据包的尾部不等于

如果 (取字节集右边 (oldData, 取字节集长度 (oldData) - 取文本长度 (temp数据包尾部)) ≠ 到字节集 (temp数据包尾部))

' 如果说不相同就说明 数据还没有完全的过来,所以这里不做任何处理

否则

处理完整传递的数据 (oldData)  ' 如果相等了,就说明数据已经完全的过来了,我们就调用数据传递后的方法

oldData = {  }  ' 这里记住,调用完毕后就必须置空字节集

如果结束

子程序 处理完整传递的数据

参数 data, 字节集

' 在这里就可以写你的处理方法了,

' by : 炫e小锋 QQ:251708339


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/10852022.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-11
下一篇 2023-05-11

发表评论

登录后才能评论

评论列表(0条)

保存