zoukankan      html  css  js  c++  java
  • 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视频2TCP发送大文件.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视频2TCP发送大文件.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 <file_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的执行权限(比串行效率高)

  • 相关阅读:
    XOR Clique
    Live Love
    Wannafly挑战赛24 A:石子游戏
    洛谷 P1060 :开心的金明
    洛谷P1049: 装箱问题
    牛客练习赛26 A:平面
    hihoCoder1151: 骨牌覆盖问题·二
    hihoCoder1143:骨牌覆盖问题·一
    hihoCoder1051 : 补提交卡
    TCP Socket的通讯框架
  • 原文地址:https://www.cnblogs.com/yangzhaon/p/10815606.html
Copyright © 2011-2022 走看看