FastSocket学习笔记~制定自已的传输协议

对于TCP或者UDP来说,它们作于传输层的协议,有着自己的标准,或者叫格式,在我们看TCP格式之前先了解一下计算机的基础知识,字节,它是计算机世界的一个小单位,也是我们可以理会到的,如一个utf-8英文字母表示一个字节(byte),而一个汉字或者一个unicode的英文字母则表示为两个字节,或者说在计算机中它将占两个字节的存储空间。而在编程世界里,通常所说的Int32,Int16,Int64这些是类型的后缀是指它占用的位数(bit,8bit=1byte),即一个int32类型的数字,占用4个字节的存储空间,其实这在之前的教课书上大家都见过,也都背过,但可能就是没有用过,学以不至用,不是一件好事,下面就让大家学以至用一下。

TCP协议格式

TCP各字段的含义

Source Port & Destination Port
如果我们将IP比喻成地址那麽Port可以说是门口了试想一下一座大楼有前门後门侧门送货的门出货的门倒垃圾的门扔死尸的门等等乱七八糟的门......

那麽一个IP地址也有着好多个各种功能的port而每一个port都被不同的服务倾听着就好比看门人一样。下面是一些常用port和其对应的服务有兴趣的
朋友可以在Linux的/etc/services这个档案找到它们
ftp-data 20/tcp
ftp 21/tcp
telnet 23/tcp
smtp 25/tcp mail
www 80/tcp http # WorldWideWeb HTTP
www 80/udp # HyperText Transfer Protocol
pop-3 110/tcp # POP version 3
pop-3 110/udp
其实port号码可以随您喜欢任意指定给哪些服务使用但为了避免“找错门口”的情形出现(除非您故意想躲起来)人们将一些比较常用的服务(Well
known
services)的port号码固定下来了。但是在TCP资料传送过程中可能同时要处理一个以上的封包程式也会建立多个port来避免突。在两台主机进
行资料传送的时候来源地的port和目的地的port都必须让TCP知道才行。
Sequence Number
发送序号。当资料要从一台主机传送去另一台主机的时候发送端会为封包建立起一个初始号码然後按照所传送的位元组数依次的递增上去那麽下一个封包的序号就会使用递增之後的值来作为它的序号了。这样接收端就可以根据序号来检测资料是否接收完整了。
Acknowledgement Number
回应序号。当接收端接收到TCP封包之後通过检验确认之後然後会依照发送序号产生一个回应序号发出一个回应封包给发送端这样接收端就知道刚才的封包已经被成功接收到了。
可是如果由於网路状况或其它原因当封包的TTL值达到期限时接收端还没接收到回应序号就会重发该个被以为丢失了的封包。但如果刚好重发封包之後才接收到回应呢这时候接收端就会根据序号来判断该封包是否被重发送如果是的话很简单将之丢弃不做任何处理就是了。
Data Offset
这是用来记录标头固定长度用的,和IP封包的IHL差不多。如果options没设定的话,其长度就是20byte,用十六进位表示就是 0x14了。
Reserved
这是保留区间暂时还没被使用。
Contral Flag
控制标记。一共有六个它们分别是: Urgent data
如果URG为1,表示这是一个携有紧急资料的封包。
Acknowledgment field significant
如果ACK为1,表示此封包属于一个要回应的封包。一般都会为1。
Push function
如果PSH为1,此封包所携带的数据会直接上传给上层应用程序而无需经过TCP处理。
Reset
如果RST为1,要求重传。表示要求重新设定封包再重新传递。
Synchronize sequence number
如果SYN为1,表示要求双方进行同步沟通。
No more data for sender (Finish)
如果FIN为1,表示传送结束,然後双方发出结束回应进而正式终止一个TCP传送过程。
Window
我们都知道MS Windows是什么东西,但这里的Window却非操作系统的“视窗”哦,这里一般称为“滑动视窗(Sliding Window)”。为什么我们需要使用视窗呢?
正如您刚才看到的TCP封包会通过SQN和ACK序号来确保传送的正确性,但如果每一个封包都要等上一个封包的回应才被发送出去的话实在是太慢和难以接受
的。这样我们可以利用Sliding Window在传送两端划分出一个范围,规定出可以一次性发送的最大封包数目。
当TCP传送建立起来之後两端都会将window的设定值还原到初始值比方说每次传送3个封包。然后发送端就一次发送三个封包出去,然后视窗则会往後移动
三个封包填补发送出去之封包的空缺。如果接收端够顺利也能一次处理接收下来的三个封包的话,就会告诉发送端的window值为3,但如果接收端太忙或是其
它因素影响暂时只能处理两个封包,那么在视窗里面就剩下一个封包,然后就会告诉发送端window值为2。这个时候发送端就只送出两个封包而视窗就会往後
移动两个封包填补发送出去的空缺。您明白为什麽这个视窗会“滑动”了吧。
其实,Window值是以字节数计算的。
Chechsum
当资料要传送出去的时候发送端会计算好封包资料大小然後得出这个检验值封包一起发送当接收端收到封包之後会再对资料大小进行计算看看是否和检验值一致如果结果不相称则被视为残缺封包会要求对方重发该个封包。
Urgent Pointer
还记得刚才讲到Control Flag的时候我们提到一个URG的标记吗如果URG被设定为一的时候这里就会指示出紧急资料所在位置。不过这种情形非常少见例如当资料流量超出频宽的时候系统要求网路主机暂缓发送资料所有主机收到这样的信息都需要优先处理。
Option
这个选项也比较少用。当那些需要使用同步动作的程式如Telnet要处理好终端的交互模式就会使用到option来指定资料封包的大小因为telnet使用的资料封包都很少但又需要即时回应。
Option的长度为0,或32bit的整倍数,如果不足则填充到满。

自己动手,搞自己的协议格式

[bodyLength int32][id int32][type int16][name char(20)][body byte[]]

下面我们来测试一个协议,为它赋值,模拟一下client和server的发送与接受的过程

            string name = "zzl";
            var message = SerializeHelper.SerializeToBinary(new UserDTO { ID = 1, Name = "repositoryUncle" });
            int bodyLength = 4 + 4 + 2 + name.Length + message.Length;
            byte[] buffer = new byte[bodyLength];
            byte[] body = new byte[bodyLength];

            #region (发送端)写入字节流
            //write message length
            Buffer.BlockCopy(BitConverter.GetBytes(bodyLength), 0, buffer, 0, 4);
            //write id.
            Buffer.BlockCopy(BitConverter.GetBytes(101), 0, buffer, 4, 4);
            //write response type.
            Buffer.BlockCopy(BitConverter.GetBytes((short)4), 0, buffer, 8, 2);
            //write response name.
            Buffer.BlockCopy(Encoding.ASCII.GetBytes(name), 0, buffer, 10, name.Length);
            //write response message.
            Buffer.BlockCopy(message, 0, buffer, 10 + name.Length, message.Length);

            #endregion

            #region (接收端)读字节流
            var messageLength = BitConverter.ToInt32(buffer, 0);
            var id = BitConverter.ToInt32(buffer, 4);
            var type = BitConverter.ToInt16(buffer, 8);
            var nameVal = Encoding.ASCII.GetString(buffer, 10, name.Length);
            var dataLength = messageLength - 10 - name.Length;
            Buffer.BlockCopy(buffer, 10 + name.Length, body, 0, dataLength);
            var obj = (UserDTO)SerializeHelper.DeserializeFromBinary(body);
            #endregion

我们在测试时,可以设置断点去观察一下messageLength,id,type,nameVal,obj等元素的值,是否正确解析了,呵呵。

最后一点要记住,协议并不难,字节流也并不神秘,关键在于坚持,不断的去探索、研究,有了这几点,再麻烦的事赞也能搞定!

时间: 2024-08-29 06:29:17

FastSocket学习笔记~制定自已的传输协议的相关文章

FastSocket学习笔记~制定自已的传输协议~续~制定基于FastSocket的协议

FastSocket这个东西上次我已经说过,它使用简单,功能强大,扩展灵活,目前在新浪的生产环境中已经被广泛使用,所以它的性能,安全等各方面我们绝对可以信赖,今天我们来说一个话题,和上一讲有关,这次我们制作一个基于FastSocket的传输协议,它的意义重大,当fastSocket提供的协议不能满足项目要求时,我们就必须硬着头皮去自己写了,还好,fastsocket为我们铺好了路,我们只要按着这条路走下去,就可以了. 自定义的协议格式如下 说干就干 首先,如果要想扩展一个自己的协议,要对 cli

马哥学习笔记二十五——ISCSI协议,架构及其安装配置

ISCSI监听在tcp/3260端口 iSCSI Target:iscsi-target-utils 客户端认正方式: 1.基于IP 2.基于用户,CHAP tgtadm:命令行工具,模式化命令 --mode 常用模式:target,logicalunit,account target --op new.delete.show.update.bind.unbind logicalunit --op new.delete account --op new.delete.bind.unbind --

【安全牛学习笔记】基本工具-常见协议包、WIRESHARK-TCP

WIRESHARK-常见协议包 数据包的分层结构 arp icmp tcp-三次握手 udp dns http ftp 例:arp 第一层包的相关信息.多少帧,大小,传输时间等统计信息 第二层数据包的内容字段.首先是目标地址,源地址.上层协议类型.  占位地段 第三arp包头. 硬件地址类型1表示以太网    协议类型ip解析成arp地址  硬件地址长度   ip地址4字节32位   操作代码  arp包头内容包含发送端的mac和ip目标端的mac和ip 例:ssdp 第一层汇总信息 第二层二层

TCP/IP学习笔记(2)----------IP协议与寻址

简介 下一博文终将会详细解析TCP/IP协议 本讲中主要注重于寻址 TCP/IP协议族中最核心的协议,提供不可靠.无连接的数据报传输服务. 不可靠:不能保证IP数据报能成功送达. 无连接:并不维护后续数据报的状态信息,每个数据报的处理都是相互独立.数据报可能不会按照发送顺序接收.同一站点向另一站点发送的多个数据报可能经过不同的路由到达. 帧格式 IP数据报格式如下. 版本:IP协议版本号,目前为4.故称为IPv4. 首部长度:以4字节为单位.最小值为5,不包含可选字段的IP首部大小为20字节.最

【安全牛学习笔记】DNS区域传输、DNS字典爆破、DNS注册信息

DNS区域传输.DNS字典爆破.DNS注册信息 ╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╋ ┃DNS区域传输                                                    ┃ ┃  dig @ns1.example.com example.com axfr    ┃ ┃  host -T -l sina.com 8.8.8.8                             ┃ ╋━━━━━━━━━━━━━━━━━

TCP/IP详解学习笔记(3)IP协议ARP协议和RARP协议

把这三个协议放到一起学习是因为这三个协议处于同一层,ARP协议用来找到目标主机的Ethernet网卡Mac地址,IP则承载要发送的消息.数据链路层可以从ARP得到数据的传送信息,而从IP得到要传输的数据信息. 1.IP协议 IP协议是TCP/IP协议的核心,所有的TCP,UDP,IMCP,IGCP的数据都以IP数据格式传输.要注意的是,IP不是可靠的协议,这是说,IP协议没有提供一种数据未传达以后的处理机制--这被认为是上层协议--TCP或UDP要做的事情.所以这也就出现了TCP是一个可靠的协议

python学习笔记-Day9 (TCP/IP协议、socket)

TCP/IP协议 TCP/IP四层协议 TCP/IP概念 tcp/ip协议是主机接入互联网以及接入互联网的两台主机通信的标准. 数据帧概念 数据帧 |-- 包头 | |--源地址 | |--目标地址 | |--数据类型 | |-- 数据 socket在四层协议中的位置 socket协议的交互流程 socket初试 # 依照上socket流程图,实现一个功能,客户端输入什么,就把输入的转为大写 # soceet server import socket ip_port=('127.0.0.1',9

学习笔记_SIP中的SDP协议

当INVITE OK, 两个UA终端之间开始音视频流传输时, SIP消息INVITE的"message body"里将携带SDP消息, 描述具体通信内容. 在Sipdroid中SDP消息的实现是SessionDescription类. 会话描述的功能: 类SessionDescription将根据SDP协议格式化(处理)SIP消息体. 会话描述的基本内容: 会话等级描述(描述可以应用于整个会话和所有媒体流); 0或者更多的媒体等级描述(描述仅只用于一种媒体流). 会话描述的详细内容:

FastSocket学习笔记~RPC的思想,面向对象的灵活

首先非常感谢这位来自新浪的老兄,它开发的这个FastSocket非常不错,先不说性能如何,单说它的使用方式和理念上就很让人赞口,从宏观上看,它更像是一种远程过程的调用RPC,即服务器公开一些命令,供客户端去调用,很灵活,而它的理念上来说,它将socket编程抽象化了,让开发人员不用去关心底层通讯机制,而只关心应用层的开发,如开发一个用户模块,你不用关心socket链接怎么声明,不用关心性能,你只要开发和用户相关的内容即可. 看一下图示,我自己画的,呵呵 看一下fastSocket自带的例子 服务