• TCP中的粘包问题,以及用TCP和UDP实现多次聊天


    TCP协议

    在连接内多和客户端说几句

    #server端
    import socket
    sk = socket.socket()
    sk.bind(('127.0.0.1',9001))
    sk.listen()
    
    while True
        conn,addr = sk.accept()
        while True
            bad = input('>>>')
            conn.send(bad.encode('utf-8'))
            if bad.upper() == 'Q':
                break
            msg = conn.recv(1024).decode('utf-8')
            if msg.upper == 'Q':break
            print(msg)
    	conn.close()  #挥手 断开连接
        
    sk.close() #归还申请的操作系统资源
    #client
    import socket
    sk = socket.socket()
    sk.connect(('127.0.0.1',9001))
    
    while True:
        msg = sk.recv(1024)
        msg2 = msg.decode('utf-8')
        if msg2.upper == 'Q':break
        print(msg2)
        send_msg = input('>>>')
        sk.send(send_msg.encode('uft-8'))
        if send_msg.upper == 'Q':break
    sk.close()
    
    

    为什么要加while True

    1. 因为要进行多次通信

    sk代表什么?

    1. sk代表启用的通信服务

    conn代表什么?

    1. conn代表自己的IP地址,和对方的地址和端口

    能够接受多个客户端的请求

    1. 为什么加while True
      1. 因为在一个客户端断开连接之后不能管不服务,要等待另一个客户端连接
    2. 怎么退出
      1. 在接收或者传输的时候先检查是不是要退出,要是退出的话就break

    UDP协议

    语法:

    #server
    import socket
    sk = socket.socket(tyep = socket.SOCK_DGRAM)
    sk.bind(('127.0.0.1',9000))
    
    msg,addr = sk.recvfrom(1024)
    print(msg.decode('utf-8'))
    msg = input('>>>')
    sk.sendto(msg.encode('utf-8'),addr)
    
    #client
    import socket
    sk = socket.socket(type = socket.SOCK_DGRAM)
    server = ('127.0.0.1',9000)
    while True:
        msg = input('>>>')
        if msg.upper == 'Q':break
        sk.sendto(msg.encode('utf-8'),server)
        msg = sk.recv(1024).decode('utf-8')
        if msg.upper() == 'Q':break
        print(msg)
    

    涉及到的新方法

    1. type = socket.SOCK_DGRAM 在开启socket方法的时候加上这段代码,表示就是用UDP协议
    2. recvfrom:在server端接收信息的时候用recvfrom就可以把客户机的IP地址获取到

    和TCP协议的区别

    1. 它可以同时建立多个连接,当一个连接断开后不会影响其他连接

    粘包现象

    1. TCP协议的特点
      1. 多条消息之间没有边界,并且还有一大堆优化算法
    2. 什么叫做粘包
      1. 多条数据粘在一起
    3. 为什么会出现粘包
      1. 发送端:两条消息都很短,发送的间隔时间也非常短
      2. 接收端:多条消息由于没有及时接收,而在接收方的缓存短堆在一起导致粘包
    4. 怎么处理
    #server
    import struct
    import socket
    
    sk = socket.socket()
    sk.bind(('127.0.0.1',9001))
    sk.listen()
    
    conn,addr = sk.accept()
    msg1 = input('>>>').encode()
    msg2 = input('>>>').encode()
    blen = struct.pack('i',len(msg1))
    conn.send(blen)
    conn.send(msg1)
    conn.send(msg2)
    sk.close()
    
    #cilent
    import struct
    import socket
    
    sk = socket.socket()
    sk.connect(('127.0.0.1',9001))
    length = sk.recv(4)
    length = struct.unpack('i',length)[0]
    msg1 = sk.recv(length)
    msg2 = sk.recv(1024)
    print(msg1.decode('utf-8'))
    print(msg2.decode('utf-8'))
    
    sk.close()
    

    什么叫自定义协议

    1. 在网络传输的时候,人为的为它定制一个协议,让它遵守此项协议

    struct模块怎么用

    1. struct.pack()#将一个数字转换为4个字节的数
    2. struct.unpack()#将一个4个字节的数,转化回原来的数

    osi五层协议

    • 应用层
    • 传输层
      • tcp协议:效率低 面向连接、可靠、全双工的通信
        • 三次握手
          • 客户端向服务器端发送syn请求
          • 服务器端向客户端回复ack并发送syn请求
          • 客户端接收到的请求之后再回复ack表示建立连接
          • 由客户端的connect + 服务端的 close
        • 四次挥手
          • 客户端向服务端发送fin请求
          • 服务端回复ack确认
          • 服务端向客户端发送fin请求
          • 客户端回复ack
          • 由客户端的close和服务端的close
      • udp协议:效率高 无连接的、不可靠
      • 四层交换机,四层路由器
    • 网络层
      • IP协议(ipv4,ipv6)
      • 路由器、三层交换
    • 数据链路层
    • arp协议,地址解析协议 通过IP找到mac地址
    • 物理层
  • 相关阅读:
    bq25896 IINDPM 及 無 IINDPM 時的 regsiter
    不同狀況下的 bq25896 register
    bq25896 charging status CHRG_STAT register 0xB
    快充 IC BQ25896 如何判斷 手機插著 adapter 充電器時,adapter Iout 大於限制,adapter Vout 小於 限制,導致 battery 不但沒充電且還需放電。
    在 kernel 下打出 有帶參數的log。 怪異現象與解決方式。
    mtk flash tool,Win7 On VirtualBox
    java 去最后一位字符 str.substring(0,str.length()-1)
    Windows下Oracle的下载与安装及配置
    关于Java中SQL语句的拼接规则
    <id name="ID"> <generator class="assigned" /> </id>
  • 原文地址:https://www.cnblogs.com/wang-xing-hao/p/11172741.html
Copyright © 2020-2023  润新知