操作socket笔记

网络编程

  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()
原文地址:https://www.cnblogs.com/RainBol/p/10150215.html