zoukankan      html  css  js  c++  java
  • 利用Python两分钟了解TCP和UDP编程实现

    TCPUDPOSI七层模型中传输层的两个协议,对应了两种传输方式

    特点如下,更多更详细请访问:TCP与UDP的全面对比

    UDP

    TCP

    是否连接

    无连接

    面向连接

    是否可靠

    不可靠传输,不使用流量控制和拥塞控制

    可靠传输,使用流量控制和拥塞控制

    连接对象个数

    支持一对一,一对多,多对一和多对多交互通信

    只能是一对一通信

    传输方式

    面向报文

    面向字节流

    首部开销

    首部开销小,仅8字节

    首部最小20字节,最大60字节

    适用场景

    适用于实时应用(IP电话、视频会议、直播等)

    适用于要求可靠传输的应用,例如文件传输

    而在Python下,两者的编程实现主要有以下区别:

    UDP

    TCP

    socket创建

    socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    数据传输

    sendto()recvfrom()

    不是一对一 所以要指明对方地址

    send()recv()

    与对方构建连接

    无需连接,直接向对方IP地址传输

    需要使用listen()accept()connect(),需要双方互相握手

    下面让我们看看在Python下两者的具体实现,从而理解其主要区别:

    ##UDP服务端
    import socket
    #建立IPv4,UDP的socket
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    #绑定端口:
    s.bind(('127.0.0.1', 9999))
    #不需要开启listen,直接接收所有的数据
    print('Bind UDP on 9999')
    while True:
        #接收来自客户端的数据,使用recvfrom
        data, addr = s.recvfrom(1024)
        print('Received from %s:%s.' % addr)
        s.sendto(b'hello, %s!' % data, addr)
    ##UDP客户端
    import socket
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    #不需要建立连接:
    for data in [b'Michael', b'ALice', b'FF']:
        #发送数据到客户端:
        s.sendto(data, ('127.0.0.1', 9999))
        #接收来自客户端的数据:
        print(s.recvfrom(1024)[0].decode('utf-8'))
    s.close()

    ——————————————————快乐分界线—————————————————————

    ##TCP服务端
    #导入socket库
    import socket
    import threading
    import time
    def deal_by_tcp(sock, addr):#新线程执行的函数
        print('Accept connection from %s:%s...'.format(addr[0],addr[1]))
        sock.send(('Welcome!').encode('utf-8'))
        while True:
            data = sock.recv(1024)
            time.sleep(1)
            #如果客户端没有发送数据或发送’exit‘:关闭连接
            if not data or data.decode('utf-8') =='exit': 
                break
            sock.send(('Hello, %s'.format(data.decode('utf-8')).encode('utf-8')))
        sock.close()
        print('Connection from %s:%s closed'.format(addr[0],addr[1]))
    
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    #绑定监听端口
    s.bind(('127.0.0.1', 9999))
    #开始监听:
    s.listen(5)  #param : 等待连接的最大数量
    print('waiting for connecting')
    while True:
        #接收一个新的连接:
        sock, addr = s.accept() #accept会等待并发返回一个客户端的连接
        #使用多线程处理:单线程在处理过程中,无法接收其他客户端的连接
        t = threading.Thread(target=deal_by_tcp, args=(sock,addr))
        t.start()  #启动线程
    ##TCP客户端
    #导入socket库
    import socket
    import io
    
    #创建一个socket:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('127.0.0.1',9999))
    s.send(b'Norton') 
    
    #接收从服务器返回的数据:
    while True:
        d = s.recv(1024) #每次最多接收1K字节
        if d:
           print(d.decode('utf-8'))
        else:
            break
    s.close()

    可以发现,TCP的构建传输的交互过程更为复杂,而传输过程更为简明且具有针对性、UDP则更加“神经大条”,适合多发和对可靠性要求不高的网络。

  • 相关阅读:
    [LintCode] Cosine Similarity 余弦公式
    Word 2010 给公式添加序号
    Xshell连接不上虚拟机的问题和解决办法
    关于 “VMware Workstation 不可恢复错误- (vcpu-0)”
    TortoiseGit客户端安装及使用(上传代码到git@osc
    Android Studio修改项目名和包名
    Android 环信(Android)设置头像和昵称的方法
    Android SharedPreferences存储map的方法
    Android 环信聊天头像昵称显示解决方案
    Android 判断当前Fragment是否可见(Visible)
  • 原文地址:https://www.cnblogs.com/Nortonary/p/12869274.html
Copyright © 2011-2022 走看看