1、TCP UDP区别:
TCP有点:可靠,稳定,TCP可靠提现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传输时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接来节约系统资源。
TCP缺点:慢、效率低、占用系统资源高,易呗攻击,TCP在传递数据之前,要先建立连接,这会消耗时间,而且在数据传输时,确认机制、重传机制、拥塞机制等都会消耗大量的时间,而且要再每台设备上维护所有的传输连接,事实上,每个连接都会占用系统的CPU,内存等硬件资源,而且,因为TCP有确认机制,这些也导致TCP容易被人利用,实现DOS、DDOS、CC等攻击。
UDP优点:快,比TCP稍安全,没有TCP的握手、确认、窗口、重传、拥塞控制等机制,UDP是一个无状态的传输协议,所以在传递数据时非常快,没有TCP的这些机制,UDP较TCP被攻击者利用的漏洞就要少一点。但UDP也是无法避免攻击的,比如UDP Flood攻击。。。
UDP缺点:不可靠,不稳定 因为UDP没有TCP那些可靠的机制,在数据传递时,如果网络质量不好,就会容易丢包。
TCP | UDP | |
是否连接 | 面向连接(TCP三次握手) | 面向非连接 |
传输可靠性 | 可靠 | 不可靠 |
应用场合 | 少量数据,安全(浏览器HTTP、FTP Outlook、SMTP Putty) | 传输大量数据(QQ语音、视频、直播等) |
速度 | 慢 | 快 |
2、TCP三次握手和四次挥手
三次握手:
初始状态:客户端A和服务器B均处于CLOSED状态,然后服务器B创建socket,调用监听接口使得服务器处于LISTEN状态,等待客户端连接。(后续内容用A,B简称代替) A首先向B发起连接,这时TCP头部中的SYN标识位值为1,然后选定一个初始序号seq=x(一般是随机的),消息发送后,A进入SYN_SENT状态,SYN=1的报文段不能携带数据,但要消耗一个序号。 B收到A的连接请求后,同意建立连接,向A发送确认数据,这时TCP头部中的SYN和ACK标识位值均为1,确认序号为ack=x+1,然后选定自己的初始序号seq=y(一般是随机的),确认消息发送后,B进入SYN_RCVD状态,与连接消息一样,这条消息也不能携带数据,同时消耗一个序号。 A收到B的确认消息后,需要给B回复确认数据,这时TCP头部中的ACK标识位值为1,确认序号是ack=y+1,自己的序号在连接请求的序号上加1,也就是seq=x+1,此时A进入ESTABLISHED状态,当B收到A的确认回复后,B也进入ESTABLISHED状态,至此TCP成功建立连接,A和B之间就可以通过这个连接互相发送数据了。
四次挥手:
初始状态:客户端A和服务器B之间已经建立了TCP连接,并且数据发送完成,打算断开连接,此时客户端A和服务器B是等价的,双方都可以发送断开请求,下面以客户端A主动发起断开请求为例。(后续内容用A,B简称代替) A首先向B发送断开连接消息,这时TCP头部中的FIN标识位值为1,序号是seq=m,m为A前面正常发送数据最后一个字节序号加1得到的,消息发送后A进入FNI_WAIT_1状态,FIN=1的报文段不能携带数据,但要消耗一个序号。 B收到A的断开连接请求需要发出确认消息,这时TCP头部中的ACK标识位值为1,确认号为ack=m+1,而自己的序号为seq=n,n为B前面正常发送数据最后一个字节序号加1得到的,然后B进入CLOSE_WAIT状态,此时就关闭了A到B的连接,A无法再给B发数据,但是B仍然可以给A发数据(此处存疑),同时B端通知上方应用层,处理完成后被动关闭连接。然后A收到B的确认信息后,就进入了FIN_WAIT_2状态。 B端应用层处理完数据后,通知关闭连接,B向A发送关闭连接的消息,这时TCP头部中的FIN和ACK标识位值均为1,确认号ack=m+1,自己的序号为seq=k,(B发出确认消息后有发送了一段数据,此处存疑),消息发送后B进入LACK_ACK状态。 A收到B的断开连接的消息后,需要发送确认消息,这是这时TCP头部中的ACK标识位值为1,确认号ack=k+1,序号为m+1(因为A向B发送断开连接的消息时消耗了一个消息号),然后A进入TIME_WAIT状态,若等待时间经过2MSL后,没有收到B的重传请求,则表明B收到了自己的确认,A进入CLOSED状态,B收到A的确认消息后则直接进入CLOSED状态。至此TCP成功断开连接。
3、socket理解:
socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口;
#!/usr/bin/python # -*- coding:utf-8 -*- import socket phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机 phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) phone.bind((‘127.0.0.1‘,8080)) #插电话卡 phone.listen(5) #开机,backlog while True: #链接循环 print(‘starting....‘) conn,addr=phone.accept() #接电话 print(‘cliet addr‘,addr) while True: #与conn的通信循环 try:#针对windows平台下客户端断开链接 client_msg=conn.recv(1024) #收消息 if not client_msg:break #针对linux系统平台下客户端断开链接 print(‘client msg: %s‘ %client_msg) conn.send(client_msg.upper()) #发消息 except Exception: break conn.close() phone.close()
原文地址:https://www.cnblogs.com/wangkc/p/10868811.html
时间: 2024-10-11 00:19:21