tcp协议的三次握手和四次挥手
SYN: 表示建立连接
FIN: 表示关闭连接
ACK: 表示响应
PSH: 表示有 DATA数据传输
RST: 表示连接重置。
CLOSED 没有使用这个套接字[netstat 无法显示closed状态]
LISTEN 套接字正在监听连接[调用listen后]
SYN_SENT 套接字正在试图主动建立连接[发送SYN后还没有收到ACK]
SYN_RECEIVED 正在处于连接的初始同步状态[收到对方的SYN,但还没收到自己发过去的SYN的ACK]
ESTABLISHED 连接已建立
CLOSE_WAIT 远程套接字已经关闭:正在等待关闭这个套接字[被动关闭的一方收到FIN]
FIN_WAIT_1 套接字已关闭,正在关闭连接[发送FIN,没有收到ACK也没有收到FIN]
CLOSING 套接字已关闭,远程套接字正在关闭,暂时挂起关闭确认[在FIN_WAIT_1状态下收到被动方的FIN]
LAST_ACK 远程套接字已关闭,正在等待本地套接字的关闭确认[被动方在CLOSE_WAIT状态下发送FIN]
FIN_WAIT_2 套接字已关闭,正在等待远程套接字关闭[在FIN_WAIT_1状态下收到发过去FIN对应的ACK]
TIME_WAIT 这个套接字已经关闭,正在等待远程套接字的关闭传送[FIN、ACK、FIN、ACK都完毕,这是主动方的最后一个状态,在过了2MSL时间后变为CLOSED状态]
二、三次握手:
在服务端执行s.listen()函数的时候,客户端发起请求连接,也就是执行connect函数.首先由client发出一个(syn=1标志位以及请求序列seq=x)的包,然后server回复一个(syn=1,seq=y,ack=x+1)的确认包表示同意连接,然后再由client发送一个(ack=y+1)确认包,连接建立
通常是服务端在每次发送完数据之后都会尝试断开连接
服务端三个重要的状态:Listen Established Close_Wait
客户端两个个重要的状态:Established Time_Wait
rvcd洪水攻击
timewait高并发
三、socket对象
socket.socket(socket_family,socket_type,protocal=0)
3个参数:
1.socket_family 可以是 AF_UNIX 或 AF_INET。
套接字家族的名字:AF_UNIX和AF_INET
基于文件类型的套接字家族:AF_UNIX
基于网络类型的套接字家族:AF_INET
unix一切皆文件,基于文件的套接字调用的就是底层的文件系统来取数据,两个套接字进程运行在同一机器,可以通过访问同一个文件系统间接完成通信
2.socket_type
socket_type 可以是 SOCK_STREAM 或 SOCK_DGRAM。
SOCK_STREAM 流式套接字指的是tcp
SOCK_DGRAM数据报指的是udp
3.protocol 一般不填,默认值为 0。
四、基于TCP协议的套接字
import socket
server=socket.socket()
server.bind(('127.0.0.1',65535)) #s.bind()里面的参数是一个元组,元组里面放的是ip和port,注意port 0-1023是系统使用的
server.listen() #liste里面的参数是最大半连接池数也就是最大接受请求数,不是最大连接数
#listen监听和accept接受连接请求数两个函数是一起出现的
while True:#通信循环
sock,c_address=server.accept() #该函数的返回值是一个元组,返回一个新的套接字以及客户端地址
while True:
try:#加上try,except是为来防止客户端突然异常断开
data=sock.recv(1024)#接受客户端传过来的数据 ,服务器和客户端之间的通讯数据以字节为单位 1024指的是最大从从操作系统的缓冲区拿1024b数据
if not data: #这个if判断只是针对于linux和mac系统,windows系统中这个if没有任何作用
sock.close() #在linux和mac系统中,一旦客户端发送数据为空会报错,所以加上这个if是为了跨平台
break
print(data.decode('utf-8'))
sock.send(data.upper())
except ConnectionResetError:
print('client异常断开')
sock.close()
break
sock.close()
server.close()
import socket
client=socket.socket()
client.connect(('127.0.0.1',65535))
while True: # 通信循环
msg=input('>>: ').strip()
if not msg:continue
client.send(msg.encode('utf-8'))
data=client.recv(1024)
print(data.decode('utf-8'))
client.close()
五、基于UDP协议的套接字
import socket
# 1.创建socket对象
s = socket.socket(type=socket.SOCK_DGRAM)
# 2.绑定端口和ip
s.bind(("127.0.0.1",10000))
while True:
# 3.接受数据
res = s.recv(1024)
print(res)
while True:
msg = input(">>>:")
s.sendto(msg.encode("utf-8"), ("127.0.0.1", 10000))
# 需要获取对方的ip和端口
# 关闭资源
s.close()
import socket
# 1.创建socket对象
c = socket.socket(type=socket.SOCK_DGRAM)
while True:
msg = input(">>>:")
c.sendto(msg.encode("utf-8"),("127.0.0.1",10000))
c.close()