TCP数据格式:

确认序号:用于连接、断开连接、传输数据时使用
标志位:一共六种,每个标志位占一个字节,URG、ACK、PSH、RST、SYN、FIN
数据:用于传输的数据
基本目前对于IP的使用只包括上面三个,要是后面还用到其他的部分,到时候会再次统一解释一下
OSI七层模型和TCP/IP4层模型:

OSI模型每个层都有一些自己的定义,这里还是给出,当然,这个并没有作为重点:
物理层:主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。它的主要作用是传输比特流(就是由1、0转化为电流强弱来进行传输,到达目的地后再转化为1、0,也就是我们常说的数模转换与模数转换)。这一层的数据叫做比特。
数据链路层:定义了如何让格式化数据以帧为单位进行传输,以及如何让控制对物理介质的访问。这一层通常还提供错误检测和纠正,以确保数据的可靠传输。如:串口通信中使用到的115200、8、N、1
网络层:在位于不同地理位置的网络中的两个主机系统之间提供连接和路径选择。Internet的发展使得从世界各站点访问信息的用户数大大增加,而网络层正是管理这种连接的层。
传输层:定义了一些传输数据的协议和端口号(WWW端口80等),如:TCP(传输控制协议,传输效率低,可靠性强,用于传输可靠性要求高,数据量大的数据),UDP(用户数据报协议,与TCP特性恰恰相反,用于传输可靠性要求不高,数据量小的数据,如QQ聊天数据就是通过这种方式传输的)。主要是将从下层接收的数据进行分段和传输,到达目的地址后再进行重组。常常把这一层数据叫做段。
会话层:通过传输层(端口号:传输端口与接收端口)建立数据传输的通路。主要在你的系统之间发起会话或者接受会话请求(设备之间需要互相认识可以是IP也可以是MAC或者是主机名)。
表示层:可确保一个系统的应用层所发送的信息可以被另一个系统的应用层读取。例如,PC程序与另一台计算机进行通信,其中一台计算机使用扩展二一十进制交换码(EBCDIC),而另一台则使用美国信息交换标准码(ASCII)来表示相同的字符。如有必要,表示层会通过使用一种通格式来实现多种数据格式之间的转换。
应用层:是最靠近用户的OSI层。这一层为用户的应用程序(例如电子邮件、文件传输和终端仿真)提供网络服务。
TCP/IP模型一直以来才是比较重要的
下面给出,基于TCP/IP模型下,两台电脑通信的过程(不是自己写的)

数据封装流程:

上面的是整个的数据封装过程,但是具体到数据本身又是怎么样的封装呢,下面给出具体到机器能看懂的数据封装是怎么样的


其实封装的过程就是一个在原有二进制序列上面不断添加新的序列,这就是封装的本质。
解封装和封装的过程相反,是一个不断减少二进制序列的过程,这是解封装的本质。
以太网帧格式:


在第一张图中,经过传输层、网络层的封装之后,获得的所有二进制序列都被当做以太网帧格式中的数据部分,可以看出第一张图中的以太网首部字节14,而以太网帧格式的目标地址+源地址+类型=14,以太网尾部是一个CRC校验码。这样就完成了整个模型的数据封装,之后就需要把数据放到网络中进行传输了(这里可能两张图看不明白,后面我会把两张图合成一张图的,等下要上课,没时间了)
ARP协议:根据IP获取Mac地址(以太网帧协议中的一种)
ARP的数据报格式:

ARP请求和ARP应答:(我觉得这里是很关键的,后面可能会出一章专门讲这个部分)

网络传输:
通过对数据的封装,之后在以太网帧协议中使用ARP请求来获得对应的Mac地址,在有了mac地址后,网络传输就可以准确的完成。这里也会提到几个概念概念:从一台主机发送ARP请求的方式也是有多种,例如广播、单播、组播等等,这里就不多介绍了。
总的来说,通过上述流程,基本已经能够实现网络传输数据这一流程,也对整个数据传输的流程有了一定的了解,后面将会具体到代码继续讲解。
server:
我在写这个服务器段的流程的时候代码还没有时间,会尽快实现相关的代码!
socket();//创建一个套接字
bind();//为套接字绑定一个地址
listen();//设置最大连接上限
accept();//阻塞客户端建立连接,成功的话返回一个新的套接字
write();//服务器向客户端发送数据
read();//服务器从客户端读取数据
close();关闭客户端
client:
socket();//创建一个用于通信的套接字
connect();//以服务器段的套接字建立连接
write();//客户端向服务器段写数据
read();//客户端从服务器段读取数据
close();//关闭客户端的套接字
三次握手:
主要用于客户端和服务器建立连接的时候使用。在TCP协议中,为了保障连接的安全和可靠性,三次握手定理在这个过程中就起到了很大的作用。这里我先用语言来描述一下三次握手。首先是客户端向服务器发起请求,发送一个SIN位,占一个字节,同时发送一个起始的随机地址,服务器在收到客户端发来的起始地址和SIN报文后,在地址上面+1,之后返回SIN和ACK报文,同时改变当前地址,当前地址=原来地址+1+数据大小(一般建立连接的时候不携带数据),客户端在收到服务器端发来的报文后,再次发送一个ACK报文,同时发起连接,当ACK报文到大服务器段后,客户端和服务器端正式建立连接。

这是一个粗略的图,下面根据具体的TCP格式来展示过程



当然在整个传输过程中,可不止只有初始化序列号和标注位的激活这么简单,里面还会带有一些其他的信息。看看TCP的长度就知道了
据我所知,在客户端和服务器端初始化序列的时候,也会初始化一下最大传送窗口,mess,传送窗口的大小就会限制数据传输,严重的话还会造成堵塞。为了解决这一问题,TCP采用滑动窗口的方式来解决数据传输中的一些问题。
滑动窗口:

TCP连接需要三次握手,而不是两次?也不是四次呢?
答:1.三次握手才可以阻止重复历史的初始化
2.三次握手才可以同步双方的初始序列号
3.三次握手才可以避免资源浪费
具体的可以参考下面的文章,后面我也会给出我对于这些答案的理解
数据通信:

上面的图是在建立连接后,客户端想要向服务期端发送数据:
1.发送一个字段,包含需要发送的20个字节的数据(1001(20))
2.服务器应答,确认需要为1001+20=1021,表示对于1001-1020的数据已经收到,同时从8001开始,发送10个字节的数据,
3.客户端应答,发送确认序号8011,表示8000-8010的数据已经完全收到,请求发送之后的数据
4.后面的依次类推,服务器端和客户端既可以发送数据,也可以同时接收数据,两者不冲突。
四次挥手:
在TCP协议中,为了保证客户端和服务器端能够在不影响各自的任务进度的情况下断开,所以使用了四次挥手来断开连接

四次挥手总结:
1.客户端发送FIN标志位,表示请求关闭
2.服务器端回答ACK,表示应答客户端的关闭请求
3.服务器端发打出自己的FIN位,表示自己已经就绪关闭,
4.客户端回应ACK,表示可以关闭
5.服务器端和客户端进入关闭状态。
总结一下:
三次握手-数据通信-四次挥手,实现了客户端和服务器整个数据传输的流程
封装思想:
多进程并发服务器:这里后面的内容,暂时就先不更新了,等到学到系统编程中的多线程内容之后,会再次更新,这部分的内容自己还不是很了解,学习的也不透彻。
在了解多进程和多线程服务器之前,大家一定要搞清楚多进程和多线程的区别,这个是基础。
fork(void):创建一个新的进程
返回值:
1)在父进程中,fork返回新创建子进程的进程ID;
2)在子进程中,fork返回0;
3)如果出现错误,fork返回一个负值;
实现思路:
1.Socket();
2.Bind();
3.Listen();
4.while(1){
cfd=Accept() ;
pid=fork();//创建子进程
}