UDP-用户数据报协议

1.介绍

UDP --- 用户数据报协议,是一个无连接的简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。

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

特点:UDP是面向无连接的通讯协议,UDP数据包括目的端口号和源端口号信息,由于通讯不需要连接,所以可以实现广播发送。 UDP传输数据时有大小限制,每个被传输的数据报必须限定在64KB之内。 UDP是一个不可靠的协议,发送方所发送的数据报并不一定以相同的次序到达接收方。
UDP是面向消息的协议,通信时不需要建立连接,数据的传输自然是不可靠的,UDP一般用于多点通信和实时的数据业务,比如

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

查看端口

  • 用“netstat -an”查看端口状态

2.udp网络程序-发送数据

socket函数
mySocket = socket(family, type)
函数socket()的参数family用于设置网络通信的域,函数socket()根据这个参数选择通信协议的族。通信协议族在文件sys/socket.h中定义。

通信协议族

函数socket()的参数type用于设置套接字通信的类型,主要有SOCKET_STREAM(流式套接字)、SOCK——DGRAM(数据包套接字)等。
并不是所有的协议族都实现了这些协议类型,例如,AF_INET协议族就没有实现SOCK_SEQPACKET协议类型。

udp网络程序-发送、接收数据

from socket import *

#1. 创建套接字
udpSocket = socket(AF_INET, SOCK_DGRAM)

#2. 准备接收方的地址
sendAddr = ('192.168.1.103', 8080)

#3. 从键盘获取数据
sendData = input("请输入要发送的数据:")

#4. 发送数据到指定的电脑上
udpSocket.sendto(sendData, sendAddr)

#5. 等待接收对方发送的数据
recvData = udpSocket.recvfrom(1024) # 1024表示本次接收的最大字节数

#6. 显示对方发送的数据
print(recvData)

#7. 关闭套接字
udpSocket.close()

echo服务器

from socket import *

# 1. 创建套接字
udpSocket = socket(AF_INET, SOCK_DGRAM)

# 2. 绑定本地的相关信息
bindAddr = ('', 7788)  # ip地址和端口号,ip一般不用写,表示本机的任何一个ip
udpSocket.bind(bindAddr)

num = 1
while True:
    # 3. 等待接收对方发送的数据
    recvData = udpSocket.recvfrom(1024)  # 1024表示本次接收的最大字节数

    # 4. 将接收到的数据再发送给对方
    #udpSocket.sendto(recvData[0], recvData[1])
    udpSocket.sendto(str(len(recvData[0].decode('gbk'))).encode('gbk'), recvData[1])

    # 5. 统计信息
    print('已经将接收到的第%d个数据返回给对方,内容为:%s' % (num, recvData[0].decode('gbk')))
    num += 1

# 5. 关闭套接字
udpSocket.close()

广播

import socket
'''
1、一对一  点对点          单播
2、一对多                  多播
3、一对所有                广播
'''
#创建socket对象
udpSocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#开启广播
udpSocket.setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,1)
#目的地:如果是''表示当前IP,如果是'<broadcast>'表示当前所在的广播地址
destAdress = ('<broadcast>',2425)
#消息内容
sendMsg = input('>>')
#编码
sendMsg = sendMsg.encode('gbk')
#发送
udpSocket.sendto(sendMsg,destAdress)

while True:
    (content,address) = udpSocket.recvfrom(1024)
    print("received from %s----%s" % (address, content.decode('gbk')))

#关闭socket对象
udpSocket.close()
print('over......')

要查看当前广播位置有3种方法

用代码给飞秋发信息

'''
    应用程序可以在通用的tcp/ip协议基础上,加上自己的判断,组成新的应用层协议。
    比如飞秋,使用的是udp协议,在此基础上包装成了IPMSG协议。
    格式:
    版本号:包编号:发送者姓名:发送者机器名:命令字:消息
    1:12323434:user:machine:32:hello
    1::13212321:易烊千玺:【易烊千玺】:32:努力来见我


    注:现行的IPMSG协议的版本是1
'''
import socket

udpSocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

destAdress = ('192.168.11.66',2425)

sendMsg = input('>.')

sendMsg = sendMsg.encode('gbk')
udpSocket.sendto(sendMsg,destAdress)

udpSocket.close()
print('over..')

运行结果:

>.1::13212321:易烊千玺:【易烊千玺】:32:努力来见我
over..

收消息_没绑定端口号

import socket

udpSocket=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
destAdress=('192.168.11.66',8888)

sendMsg = input('--')

sendMsg = sendMsg.encode('gb2312')

udpSocket.sendto(sendMsg,destAdress)

recvMsg=udpSocket.recvfrom(1024)
recvMsg='【Receive from %s : %s 】: %s'%(recvMsg[1][0],recvMsg[1][1],recvMsg[0].decode('gbk'))
print(recvMsg)

udpSocket.close()
print('over.......')

收消息_绑定端口

import socket

#创建socket对象
udpSocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
'''
绑定,
第一个参数是本地ip,不指定也可以,默认会帮你填充,建议不写
第二个参数是端口号,不要与本地的端口号冲突
'''
localAdress = ('',8081)
udpSocket.bind(localAdress)
#目的地
destAdress = ('192.168.11.66',8888)
#消息内容
#sendMsg = input('>>')
#编码
#sendMsg = sendMsg.encode('gb2312')
#发送
#udpSocket.sendto(sendMsg,destAdress)

'''
收,这个缓冲区不是越大越好,如果发送方的数据,大于缓冲区,丢包,报错。
如果收不到,阻塞
'''
recvMsg = udpSocket.recvfrom(1024)
recvMsg = '【Receive from %s : %s】:%s'%(recvMsg[1][0],recvMsg[1][1],recvMsg[0].decode('gbk'))
print(recvMsg)

#关闭socket对象
udpSocket.close()
print('over......')

多线程聊天

'''
收和发互相不影响:
    这是两个独立的功能,可以考虑两个线程
'''
from socket import *
from threading import *
import  os

'''全局变量'''
# socket
udpSocket = None
# ip
destIp = None
# port
destPort = None


# 收
def recv():
    while True:
        recvInfo = udpSocket.recvfrom(1024)
        print("\r<<%s:%s%s>>" % (str(recvInfo[1]), recvInfo[0].decode('gbk'),os.linesep),end='')


# 发
def send():
    while True:
        info = input('>>')
        udpSocket.sendto(info.encode('gbk'), (destIp, destPort))


# 主方法
def main():
    global udpSocket
    global destIp
    global destPort

    udpSocket = socket(AF_INET, SOCK_DGRAM)
    bindAddr = ('', 8888)  # ip地址和端口号,ip一般不用写,表示本机的任何一个ip
    udpSocket.bind(bindAddr)

    #destIp = input("对方的ip:")
    #destPort = int(input("对方的port:"))
    destIp = '192.168.11.66'
    destPort = 8080

    tSend = Thread(target=send)
    tRecv = Thread(target=recv)

    tSend.start()
    tRecv.start()


if __name__ == '__main__':
    main()

结果:

>>北方有佳人
<<('192.168.11.66', 8080):遗世而独立
>>一顾倾人城
<<('192.168.11.66', 8080):再顾倾人国
>>

注释

  • os.linesep字符串给出当前平台使用的行终止符。例如,Windows使用'\r\n',Linux使用'\n'而Mac使用'\r'。
  • \r 默认表示将输出的内容返回到第一个指针,这样的话,后面的内容会覆盖前面的内容
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容

  • 11.1 引言 UDP是一个简单的面向数据报的运输层协议:进程的每个输出操作都正好产生一个UDP数据报,并组装成一...
    张芳涛阅读 2,799评论 1 6
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,934评论 6 13
  • 1.这篇文章不是本人原创的,只是个人为了对这部分知识做一个整理和系统的输出而编辑成的,在此郑重地向本文所引用文章的...
    SOMCENT阅读 13,051评论 6 174
  • 个人认为,Goodboy1881先生的TCP /IP 协议详解学习博客系列博客是一部非常精彩的学习笔记,这虽然只是...
    贰零壹柒_fc10阅读 5,051评论 0 8
  • 因为学历低所以很早就上班了,不比现在大学生出来工作都25、26岁。20才出头的时候,哪里懂得要学习,上一天班混一天...
    在水一方含阅读 171评论 1 5