python 通信协议_python网络编程(通过tcp或者udp协议通信)

1、基于tcp协议传送文件:

客户端:

import socket

import os

import json

import struct

client = socket.socket()

client.connect(('127.0.0.1',8080))

# 文件大小

file_size = os.path.getsize(r'F:\老男孩Python7期\day32\视频\02TCP发送大文件.mp4')

# 文件名字

file_name = 'TCP发送大文件.mp4'

# 定义一个字典

d = {

'file_name':file_name,

'file_size':file_size

}

data_pytes = json.dumps(d).encode('utf-8')

# 制作报头

header = struct.pack('i',len(data_pytes))

# 发送报文

client.send(header)

# 发送字典

client.send(data_pytes)

# 发送真实数据

with open(r'F:\老男孩Python7期\day32\视频\02TCP发送大文件.mp4','rb') as f:

for lie in f:

client.send(lie)

服务端:

import socket

import struct

import json

import os

server = socket.socket()

server.bind(('127.0.0.1',8080))

server.listen(5)

while True:

conn,addr = server.accept()

while True:

try:

# 接收报头

header = conn.recv(4)

# 解析报头,获取长度

header_len = struct.unpack('i',header)[0]

print('长度为'+header_len)

# 接收字典,其中header_len显示为接收内容的长度

header_bytes = conn.recv(header_len)

header_dic = json.loads(header_bytes.decode('utf-8'))

print(header_dic)

# 根据字典中的key获取对应的value

file_name = header_dic['file_name']

file_size = header_dic['file_size']

resc_size = 0

# 文件操作

with open(file_name,'wb') as f:

while resc_size

data = conn.recv(1024)

f.write(data)

resc_size += len(data)

except ConnectionRefusedError:

break

conn.close()

2、UDP协议通信(由于没有双通道,不会出现沾包、客户端中断或者服务端中断不影响、客户端可以发空内容)

客户端:

import socket

client = socket.socket(type=socket.SOCK_DGRAM)

service_addr =('127.0.0.1',8080)

while True:

msg = input('输入要发送的消息:')

msg = '客户发送的消息:%s' % msg

client.sendto(msg.encode('utf-8'),service_addr)

data,addr = client.recvfrom(1024)

print(data.decode('utf-8'))

print(addr)

服务端:

import socket

service = socket.socket(type=socket.SOCK_DGRAM)

service.bind(('127.0.0.1',8080))

while True:

msg,addr = service.recvfrom(1024)

print(msg.decode('utf-8'))

print(addr)

data = input('请输入回复消息:').encode('utf-8')

service.sendto(data,addr)

基于sockerServer模块下tcp和udp高并发通讯

这里的高并发并不是真正意义上的高并发,是看起来像是同时运行的就成为并发

# 注意事项:udp在测试高并发的时候不要默认循环测试,最好使用客户端使用一些io操作,不然会出现卡死现象

1、基于tcp的sockerServer模块使用

客户端:

import socket

client = socket.socket()

client.connect(('127.0.0.1',8080))

while True:

msg = input('请输入要发送的消息:').encode('utf-8')

client.send(msg)

data = client.recv(1024)

print(data.decode('utf-8'))

服务端:

import socketserver

class Mybaby(socketserver.BaseRequestHandler):

def handle(self):

while True:

data = self.request.recv(1024)

print(data.decode('utf-8'))

msg = input('请输入要发送的消息:').encode('utf-8')

self.request.send(msg)

if __name__ == '__main__':

server = socketserver.ThreadingTCPServer(('127.0.0.1',8080),Mybaby)

server.serve_forever()

2、基于UDP通信

客户端:

import socket

import time

client = socket.socket(type=socket.SOCK_DGRAM)

service_addr = ('127.0.0.1', 8080)

while True:

client.sendto(b'hello world',service_addr)

data, addr = client.recvfrom(1024)

print(data)

print(addr)

time.sleep(2)

服务端:

import socketserver

class MyBaby(socketserver.BaseRequestHandler):

def handle(self):

while True:

data,sock = self.request

print(data)

print(self.client_address)

sock.sendto(data,self.client_address)

if __name__ == '__main__':

server = socketserver.ThreadingUDPServer(('127.0.0.1',8080),MyBaby)

server.serve_forever()

总结:1、为什么会出现粘包现象?  只有在tcp协议中才会出现粘包现象,因为tcp协议是流式协议

特点是将数据量比较小且间隔时间短的数据一次性打包发送出去,本质还是因为我们不知道需要接收数据的长短。2、怎么解决粘包?  1、发送数据先告诉对方数据量的大小

2、利用struct模块定制自己的消息传输协议UDP协议:  1、udp协议客户端允许发空内容。

2、udp协议不会出现粘包。

3、udp协议服务端不存在的情况下,客户端照样不会报错。

4、udp协议支持并发。

udp协议叫数据协议,发消息接收消息都带有报头

upd的service不需要监听也不需要建立连接

在启动服务后只能被动的等待客户端发送消息过来,客户端发送消息过来的时候,带上服务端的地址,服务端回复消息的时候,也到带上客户端的地址。

并发编程:

多道技术的产生:

解决cpu在执行程序,遇到io时,cpu不干活的情况

串行:一个程序完完整整的运行完毕,才能运行下一个程序。

并发:看上去像是同时运行。

多道技术:

空间上的复用(多个程序共用一套硬件设别,它是多道技术实现时间上的复用的基础。)

时间上的复用(单个cpu的电脑上,起多个应用程序,cpu快速切换,给人的感觉是同时运行)

一个任务占用cpu时间过长或被操作系统强行剥夺走cpu的执行权限(比起串行效率而降低)

一个任务执行过程中遇到io操作(等待时间),也会被操作系统强行剥夺cpu的执行权限(比串行效率高)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值