网络编程
1.tcp协议
#tcpserver #单纯一对一发 tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建tcp套接字 参数(ipv4,tcp) tcp.bind(('127.0.0.1', 8000)) # 为服务端创建本地绑定信息 参数为元组 '' 代表绑定本地 端口要求int类型 tcp.listen() # listen(n)监听模式 默认套接字变为被动等待为触发 client_socket, clent_socket_address = tcp.accept() # 阻塞 等待客户端连接 返回值为元组 (socket套接字,客户端的地址) while True: if client_socket: print("连接成功!") print("client_socket:", client_socket) print("clent_socket_address:", clent_socket_address) recv = client_socket.recv(1024) # 服务端 接收 1024为接收的最大数据大小 print("-->:", recv.decode('utf-8')) client_socket.send('这里是rainbol的客户端请求'.encode('utf-8')) # 服务端回复,服务端发送时需要bytes类型 client_socket.close() tcp.close()
#tcpclient #客户端 tcp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM) tcp_socket.connect(('127.0.0.1',8000)) while True: data = input('-->:') tcp_socket.send(data.encode('utf-8'))#把字符串转成二进制,并把发送data recv_data = tcp_socket.recv(1024)# 接收服务端返回的消息 print('-->%s'%recv_data.decode('utf-8')) tcp_socket.close()
粘包问题
#client
''' 黏包现象:tcp传输过程中基本传输1500字节后就要进行分包处理,发送端默认进行拆包,接收端进行合包 一种是因为发送数据包时,每次发送的包小,因为系统进行优化算法,就将两次的包放在一起发送,减少了资源的重复占用。多次发送会经历多次网络延迟,一起发送会减少网络延迟的次数。因此在发送小数据时会将两次数据一起发送,而客户端接收时,则会一并接收。#即出现多次send会出现黏包 第二种是因为接收数据时,又多次接收,第一次接收的数据量小,导致数据还没接收完,就停下了,剩余的数据会缓存在内存中,然后等到下次接收时和下一波数据一起接收。 为了校验数据的完整 ''' '解决黏包:本质是因为我们在传输时不知道该数据包到底多大,取决于服务端和客户端相互协定如下方式' import socket import struct soc = socket.socket() soc.connect(('127.0.0.1',9000)) msg = b'hello' msg_len = struct.pack('i',len(msg))#反正粘包现象,使用struct模块发送tcp数据时一开始告诉服务器发送字节数的大小,struct的i参数可以把8位数字节数以4个字节数类似'/SAD/sadsa/sad/sadasd'先发送给服务端 soc.send(msg_len) soc.send(msg) msg = b'world' msg_len = struct.pack('i',len(msg)) soc.send(msg) soc.close()
#server import socket import struct server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(('127.0.0.1',9000)) server.listen() client_socket, clent_socket_address = server.accept() get_lens = client_socket.recv(4)#先拿4个字节 get_size = struct.unpack('i',get_lens)[0] #拿到数据长度 msg1 = client_socket.recv(get_size) #再接收所有数据 print(msg1) get_lens = client_socket.recv(4)#先拿4个字节 get_size = struct.unpack('i',get_lens)[0] #拿到数据长度 msg2 = client_socket.recv(get_size) print(msg2)
2.udp协议
#server import socket soc = socket.socket(type=socket.SOCK_DGRAM)#默认tcp如果变成udp要加SOCK_DGRAM soc.bind(('127.0.0.1',9000)) ret,client_addr = soc.recvfrom(1024) print(ret) soc.sendto(b'ok',client_addr)#返回给客户端接收成功 soc.close()
#client import socket soc = socket.socket(type=socket.SOCK_DGRAM) ret = soc.sendto(b'helloworld',('127.0.0.1',9000)) #参数一:想要发送的byte字节,参数二:想要发送给谁的地址 msg = soc.recv(1024)#接收服务端返回结果 print(msg) soc.close()