python网络编程 - udp

UDP简介

用户数据报协议,是一个无连接的面向数据报的运输层协议。

UDP不提供可靠性,它只是把应用程序传给IP层的数据报发出去,但是并不能保证他们能到达目的地。

由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。

UDP是一种面向无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。

UDP可以理解为写信,TCP可以理解为打电话。

UDP在互联网中的丢包率几乎为0,在互联网中(美国到中国),丢包率也很低,但是始终还是存在丢包的可能

UDP特点

UDP是面向无连接的通讯协议

UDP数据包括目的端口号和源端口号信息

通讯不需要建立连接,所以可以实现广播发送

UDP传输数据有大小限制,每个被传输的数据报必须限定在64KB之内

UDP是一个不可靠的协议,发送方发送的数据报并不一定以相同的次序到达接收方

适用场景

多点通信和实时性要求高的场景

UDP是面向消息的协议,通信时不需要建立连接,数据的传输自然是不可靠的,UDP一般用于多点通信实时的数据业务员,如:

语音广播、视频、QQ、TFTP(简单文件传送)、SNMP(简单网络管理协议)、RIP(路由信息协议,如报告股票市场,航空信息)、DNS(域名解释)

注重速度流畅的场景

UDP操作简单,而且仅需要较少的监护,因此通常用于局域网高可靠性的分散系统中的client/server应用程序。如:视频会议系统,并不要求音频视频数据绝对的正确,只要保证连贯性就可以了,这种情况下显然使用UDP会更合理。

 

UDP的Python程序

发送/接收数据

流程

创建一个UDP的程序的流程很简单,如下:

1、创建客户端套接字

2、发送/接收数据

3、关闭套接字

原理 

 

 

UDP绑定信息

为什么要绑定信息

一般情况下,在一台电脑上运行的网络程序很多,而各自用的端口号很多情况下是不知道的,为了与其他的网络程序占用同一个端口号,往往在代码中,udp的端口号是不绑定的。

 

对于发送方(客户端程序),端口号随机分配问题不大,但是对于接收方(服务器)来说,最好绑定一个固定的端口,那么别人往服务器发送数据的时候,只需要往约定好的端口发送数据即可。想想如果服务器的端口号是任意的,那么每次往服务器发送数据的时候还需要确定端口号,但是服务器的端口号是随机的,如何确定?!

 

如果是一个服务器端的程序的话,就需要绑定端口号了。想想如果报警电话每天都在变,想必世界就会乱了,所以一般服务性的程序,往往需要一个固定的端口号,这就是所谓的端口绑定

 

 报警电话为110,只能定死,而拨打110的号码,可以是手机,可以是别人的手机,可以是座机,可以是公用电话等等。可见绑定端口,一般是接收方(服务器)才需要绑定端口,而发送方是不需要绑定端口。

 

几个概念

听:接收

说:发送

单工:如收音机,只能听,不能说话

半双工:如对讲机,当某个人在说话时,你不能说话,当没人说话时,你可说话

全双工:如电话,可以同时说话。socket就是全双工的,在接收数据的同时也可以发送数据

 

python代码实现

服务端

# coding:utf-8

import socket
import config


def main():
    # 创建udp的套接字
    sk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    # 重用ip和port,防止报错
    sk.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    # 绑定ip和port
    sk.bind((config.host, config.port))

    if config.connected:
        # 要建立连接
        nsk, addr = sk.accept()
        # 通过新的socket去接收数据
        data = nsk.recv(1024)

    else:
        # 不用建立连接,只有udp才能这么写,tcp是必须先建立连接的
        data, addr = sk.recvfrom(1024)

    print(data)


if __name__ == '__main__':
    main()

 

客户端

# coding:utf-8

import socket
import config


def main():
    # 创建udp的套接字
    sk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    # 地址
    addr = (config.host, config.port)

    # 要发送的内容
    send_data = b"hello"

    if config.connected:
        # 要建立连接
        sk.connect(addr)
        sk.send(send_data)
    else:
        # 不用建立连接
        sk.sendto(send_data, addr)


if __name__ == '__main__':
    main()

 

posted @ 2019-10-31 16:25  goodup  阅读(563)  评论(0编辑  收藏  举报

如有不对之处,欢迎指出,一起成长