zoukankan      html  css  js  c++  java
  • python socket的应用 以及tcp中的粘包现象

    1,socket套接字

       一个接口模块,在tcp/udp协议之间的传输接口,将其影藏在socket之后,用户看到的是socket让其看到的。

     在tcp中当做server和client的主要模块运用

    #server
    sk = socket.socket()
    sk.bind(('127.0.0.1',9000))#绑定一个端口IP地址和端口
    sk.listen()   #接收数据
    conn,addr = sk.accept()  #获取接收数据的主内容和ip地址
    count= conn.recv(1024).decode('utf-8') #接收过程中只能接收字节码,并且在此处设置一次接收最多1024个字节
    print(count)
    conn.send('HI'.encode('utf-8'))#传输数据也只能传输字节码,此处传输没有大小限制
    conn.close()
    sk.close() #以上为server服务端的传输接收方式,利用socket实现 #client sk = socket.socket() sk.connect(('127.0.0.1',9000)) #此处为链接一个服务器 sk.send('hello'.encode('utf-8'))# 客户端需要与服务端一一对应,接收和传输需要统一配合 k = sk.recv(1024).decode# 接收服务端的信息 print(k) sk.close()#注意关闭 #此为客户端的socket的基本联通方式

     在udp中当做server和client的主要模块运用

    #server端口
    sk = socket.socket()
    sk.bind(('127.0.0.1',9000))
    conn,addr = sk.recvfrom(1024)#与tcp的不同接收方式,tcp是accept而udp则是recvfrom,但是同样为两个参数
    print(conn.decode('utf-8'))
    conn.sendto('hi'.encode,addr)#由于udp支持点对点的地址传输,此时在末尾加入地址参数,点对点传输,
    sk.close()
    
    #client端口
    in_point = ('127.0.0.1',9000)   #由于udp是可无需链接的  所以直接利用ip地址和端口号对服务端进行交互
    sk = socket.socket()
    sk.sendto('hi'.encode('utf-8'),in_point) 
    conn,addr = sk.recvfrom(1024)    
    print(conn.decode('ut-8'),addr)    #不同于tcp协议  两边的传输和接收几乎相同,所以使用recvfrom接收的时候同样拥有两个参数
    
    sk.close()
    

       由于udp的特性,在联通中可以使用重构socket从而使得传输的功能和目的更好的实现。

    2.tcp中的粘包现象

      1,什么是粘包:利用tcp传输文件时,由于不知道哪里断句,并且第一次和第二次的传输间隔过小,则会出现被判断为一个文件,从而是的上下两个内容粘合到一起,因此产生了粘包现象

      

      2,为什么会出现粘包:

          1,同时发送多个文件,并且文件间隔时间和文件的大小都小于一个拆包空间的时候,由于tcp的内部算法会将它们整合到一起发送,就会出现粘包现象

          2,发送的文件较大,超过了网口的MTU值,(一般在1500左右)在拆包的过程中分成多个小块,而在读取的时候可能将后序的文件也分到同一个小块中,从而产生粘包现象。

      #注udp永远不会出现粘包现象:算法不同,而且udp有明确的区分传输的方法,传输的每段内容都有区分,因此不会出现粘包

      3,解决粘包的方法:

        1,获取文件的传输大小,两边统一接收和传输的数据流大小,做到不会粘包

        2,利用struct模块,发送报头的方式来区分文件的传输  struct.pac('i',len(文件长度))

        

    #server端口
    import os
    import json
    import socket
    import struct
    
    #服务器传输文件!
    dic = {'filename': '02 python fullstack s11day34 tcp拾遗和udp协议.mp4',
           'filesize': os.path.getsize(r'D:python_filepython11期day34视频2 python fullstack s11day34 tcp拾遗和udp协议.mp4')}   #设置一个字典,字典中包含文件的所有信息统一处理
    sk = socket.socket()
    sk.bind(('127.0.0.1',9000))
    sk.listen()
    dic = json.dumps(dic)      #文件的传输利用json的方式编码传输
    dic_send = struct.pack('i', len(dic))   #struct模块进行基本的报头传输
    conn,addr = sk.accept()
    conn.send(dic_send)
    conn.send(dic.encode('utf-8'))
    with open(r'D:python_filepython11期day34视频2 python fullstack s11day34 tcp拾遗和udp协议.mp4','rb') as f:
        while True:
            k = f.read(8192)         #文件的写入大小统一大小
            if k:
                conn.send(k)
            else:break
    
        conn.close()
        sk.close()
    
    ###########################################################
    
    #client端口
    import os
    import json
    import socket
    import struct
    
    #接收文
    sk = socket.socket()
    sk.connect(('127.0.0.1',9000))
    conn = sk.recv(4)
    conn = struct.unpack('i',conn)[0]    #此处接收需要注意接收的是一个元祖,第一个为被压缩的四个字节内容,是字典的长度
    mag = sk.recv(conn).decode('utf-8')#再次接收的就是json后的字典
    mag = json.loads(mag)#解码后获得字典中的数据
    with open(r'C:UsersAdministratorDesktop视频2 python fullstack s11day34 tcp拾遗和udp协议.mp4','wb') as f:
        while mag['filesize']:
            conn = sk.recv(8192)
            mag['filesize'] -= len(conn)
            f.write(conn)
            # if conn:
            #     f.write(conn)
            # else:break
    
        sk.close()                                
    

      

  • 相关阅读:
    [LintCode] Valid Palindrome 验证回文字符串
    [LeetCode] 378. Kth Smallest Element in a Sorted Matrix 有序矩阵中第K小的元素
    [LintCode] Integer to Roman 整数转化成罗马数字
    [LintCode] Roman to Integer 罗马数字转化成整数
    [LintCode] Scramble String 爬行字符串
    [LintCode] Count and Say 计数和读法
    [LintCode] Simplify Path 简化路径
    [LintCode] Length of Last Word 求末尾单词的长度
    [LintCode] Valid Parentheses 验证括号
    [LeetCode] 377. Combination Sum IV 组合之和之四
  • 原文地址:https://www.cnblogs.com/wpcbk/p/9048512.html
Copyright © 2011-2022 走看看