TCP核心意涵与基本原理

1)TCP的核心意涵是什么?
	a.面向连接的;
	b.可靠的传送协议;

2)TCP的连接管理全过程(如何管理这么多客户端的):
	(1)客户端和服务端之分;
		服务器等待客户端连接进来;
		客户端主动去连接服务器;

	(2)网络设备: 网卡来收发我们的数据,那么每块网卡在我们的网络上你可以理解为唯一
			的一个地址-->IP地址, 有IPV4和IPV6之分;

	(3)网络数据包的传送,就是从一个IP地址传送给另外的一个IP地址的设备;

	(4)端口: 我们电脑、手机只有有限的网卡个数(1个,一般2个就不得了了),不同的应用程序来使用同一个网卡,那么如何保证数据不会乱呢?
		  也就是实现一边听在线音乐,一边打游戏呢?
		  这就是OS在我们使用应用的时候,有个端口的概念,N个端口供我们的app使用;
		  所以你要使用一个端口+网卡-->来收发数据,网卡上就好像有多个口一样,用一个口则接入一个;
		  端口如果被占用,你再去使用就会报错-->找一个没有使用的端口;
		  虚拟端口有6W多个;
    
    (5)游戏服务器: 虽然我们要对接几万、几十万玩家同时在线-->使用有限端口来处理,开始运行的时候,就会占用好端口;
    	5000人同时在线,并不是说: 就要占用5000个端口;

    	文件描述符???
    	IO多路复用: select epoll-->也就是NIO,不是让一个线程对应一个连接。 并不是实时都有数据-->优化下

    step1: 服务器在服务器电脑上创建一个socket,占用一个端口,监听socket,监听端口;
    		同时服务器利用网卡收发数据都使用这个端口;

    step2: 客户端创建一个socket,在客户端的机器上也要找一个没有使用的端口(这个端口可以使任意的,没被使用即可):
    
    step3: 客户端,通过这个socket-->端口-->网卡, 目标IP地址+端口,投递一个 "连接请求数据包";

    step4: 服务端就会收到一个客户端的连接请求的数据包: 服务器IP+端口是固定的,只有固定了,我们的客户端才知道事件往哪里投放; 	

    step5: 服务器接收这个连接请求后,给这个客户端,创建一个"新的socket", 专门与客户端对接,使用的依然是这个端口;	

    step6: 有了专门的数据通道以后,服务器就和这个客户端建立起来了我们的数据收发通道;
    		客户端socket发送数据包的时候-->IP+端口;
    		这样服务器端的数据就可读, 服务器发现这次不是连接请求,于是去找时哪个socket与之对应, 知道了某某客户端发送过来了消息;

    step7: 服务器上面的socket对象保存了和它连接的客户端的socket信息,客户端IP地址+客户端端口-->服务器socket-->
    			客户端的socket来投递我们的数据包;

    step8: 关闭: 客户端要主动关闭socket,会向我们的服务端发送关闭请求,服务器的底层,回应一个OK,服务器的底层也发送一个关闭请求,
    			客户端回复一个OK,就关闭了,连接就断开了,就无法再通过socket收发数据的. 关闭socket,释放系统资源;

    step9: 服务器利用TCP来管理成千上万个客户端,实际就是管理成千上万个socket,收据的收发;

    收数据;
    发数据;

    连接进来;
    连接断开;

3)TCP可靠的网络传送原理:
	(1)由于数据要经过漫长的传送,因此可能会丢包;
	(2)某些路径快一些,会导致我们先发的数据后到,后发的数据先到;

	网络在实际的传送过程中,实际是不可靠的;
	我们希望用户不用管不可靠性,使用TCP的时候,它就是可靠的,操作OS底层来给你处理,让你觉得TCP是可靠的;

	我们说TCP是可靠的传送: 对TCP socket的用户而言是可靠的;
	OS底层实现了TCP的可靠传输网络协议;
	底层每发送一个数据包-->等到对方回复确认收到以后,再发送下一个数据包;
	假设一段时间没有等到回复,我们会重发这个数据包,直到收到这个数据包;   

	tcp.send("hello")
	tcp.send("blake")
	tcp.send("bycw")

	那么收到的一定是helloblakebycw,而不可能是hellobycwblake,因为如果blake没有收到,是不会发送bycw的,这就是TCP协议栈帮我们做的事情,
		我们只要使用就行了,也就是TCP对业务而言是不会丢包的;

4)TCP传送可靠的代价:
	(1)我们每次发送一个数据包,都要经过确认,以后才会发送下一个数据包,TCP发送数据包,会"卡住"后面的包;

	(2)每次TCP我们都要确认,所以为了高效,尽可能等更多的数据一起发送,这一等 等出来"粘包" "半包" 2个经典问题:
		App: tcp.send("blake"); tcp.send("bycw")    接收:blakebycw, 收到一次数据包,而这个数据包,包含了2个命令,这就是著名的"粘包"问题;

		底层每次发送的数据大小是有限制的,那么这个时候, blakebyc   w-->1个数据包分为了2次发送, 这就是"半包"问题;

		tcp-->经典模块: tcp封包与拆包:
			因此我们发送之前,需要做一个盒子[大小 + 数据内容]--》因此受收到数据后,就可以割出来我们需要的内容;
			分割符号: blake\r\nbycw\r\n

	(3)TCP对于应用层来说是不可能出现: "丢包" "时序"问题:
		1 2 3--》一定收到 1 2 3,不可能收到1 3 或者 3 2 1


思考:
    TCP如何做连接管理的?
    TCP如何做到可靠的?
    总结TCP可靠给我们带来的问题?
发布了1620 篇原创文章 · 获赞 144 · 访问量 179万+

猜你喜欢

转载自blog.csdn.net/themagickeyjianan/article/details/105425530
今日推荐