python网络-Socket之udp编程(24)

 

1、udp简介

  • udp --- 用户数据报协议,是一个无链接的简单的面向数据报的运输层协议。
  • udp不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,可是并不能保证它们能到达目的地。
  • udp在传输数据报前不用在客户和服务器之间创建一个链接,且没有超时重发等机制,故而传输速度很快。
  • udp是一种面向无链接的协议,每一个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,所以可否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。

 

2、udp特色:

udp是面向无链接的通信协议,udp数据包括目的端口号和源端口号信息,因为通信不须要链接,因此能够实现广播发送。 udp传输数据时有大小限制,每一个被传输的数据报必须限定在64KB以内。 udp是一个不可靠的协议,发送方所发送的数据报并不必定以相同的次序到达接收方。udp是面向消息的协议,通讯时不须要创建链接,数据的传输天然是不可靠的,udp通常用于多点通讯和实时的数据业务,好比:html

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

 

3、udp网络程序-发送数据

建立一个udp客户端程序的流程是简单,具体步骤以下:linux

  1. 建立客户端套接字
  2. 发送/接收数据
  3. 关闭套接字

代码以下:编程

#coding=utf-8
from socket import *

#一、建立socket套接字 #socket(参数1,参数2) #参数1 = AF_INET固定的 #参数2 = SOCK_DGRAM表示udp,上篇文章中说过SOCK_STREM表示tcp
udpSocket = socket(AF_INET,SOCK_DGRAM) #二、准备接收方的地址
sendAddress = ("192.168.100.101",8080) #三、从键盘输入须要发送的数据
sendData = input("请输入要发送的数据:") #四、发送数据到指定电脑
udpSocket.sendto(sendData.encode(),sendAddress) #五、关闭socket套接字
udpSocket.close()

运行程序:windows

这个时候我就向个人另一台IP地址为:192.168.100.101 端口号为8080的程序发送了“我是侯哥”这一条消息。咱们借助于网络调试助手软件用于测试,网络调试助手各个平台的系统都有,你们能够本身下载使用。服务器

说明:个人代码是在windows电脑上运行的,个人网络调试助手是在Mac电脑上运行的,若是没有两台电脑的,也可使用虚拟机测试。网络

 

4、udp网络程序-接收数据

#coding=utf-8
from socket import *

#一、建立socket套接字
udpSocket = socket(AF_INET,SOCK_DGRAM) #二、准备接收方的地址
sendAddress = ("192.168.100.101",8080) #三、从键盘输入须要发送的数据
sendData = input("请输入要发送的数据:") #四、发送数据到指定电脑
udpSocket.sendto(sendData.encode(),sendAddress) #五、等待接收对方发送的数据
receiveData = udpSocket.recvfrom(1024) #六、显示对方发送的数据
print(receiveData) #七、关闭socket套接字
udpSocket.close()

运行程序:多线程

 

5、udp网络程序-端口问题

会变的端口号:从新运行屡次脚本,而后在“网络调试助手”中,看到的现象以下:并发

说明:app

  • 每从新运行一次网络程序,上图中红圈中的数字,不同的缘由在于,这个数字标识这个网络程序,当从新运行时,若是没有肯定到底用哪一个,系统默认会随机分配
  • 记住一点:这个网络程序在运行的过程当中,这个就惟一标识这个程序,因此若是其余电脑上的网络程序若是想要向此程序发送数据,那么就须要向这个数字(即端口)标识的程序发送便可

 

6、udp绑定信息

通常状况下,在一天电脑上运行的网络程序有不少,而各自用的端口号不少状况下不知道,为了避免与其余的网络程序占用同一个端口号,每每在编程中,udp的端口号通常不绑定,可是若是须要作成一个服务器端的程序的话,是须要绑定的。就像报警电话天天都在变,想必世界就会乱了,因此通常服务性的程序,每每须要一个固定的端口号,这就是所谓的端口绑定socket

绑定示例

#coding=utf-8
from socket import *

#一、建立socket套接字
udpSocket = socket(AF_INET,SOCK_DGRAM) #二、绑定相关信息,若是一个网络程序不绑定,则系统会随机分配
bindAddress = ("",7781)#ip地址和端口号,ip通常不用写,表示本机的任何一个ip
udpSocket.bind(bindAddress) #三、等待接收方发送消息
receiveData = udpSocket.recvfrom(1024) #四、显示对方发送的数据
print(receiveData) #五、关闭socket套接字
udpSocket.close()

windows电脑发送信息

mac电脑接收信息以下:

说明:

  • 一个udp网络程序,能够不绑定,此时操做系统会随机进行分配一个端口,若是从新运行次程序端口可能会发生变化
  • 一个udp网络程序,也能够绑定信息(ip地址,端口号),若是绑定成功,那么操做系统用这个端口号来进行区别收到的网络数据是不是此进程的

 

7、udp网络通讯过程

 

8、udp应用:多线程对话聊天实现

#coding=utf-8
from threading import Thread from socket import *

#接收数据
def receiveInfo(): while True: receiveData = udpSocket.recvfrom(1024) print("<<%s:%s"%(str(receiveData[1]),str(receiveData[0]))) #发送数据
def sendInfo(): while True: sendData = input("") udpSocket.sendto(sendData.encode("gb2312"),(destIp,destPort)) udpSocket = None destIp = "" destPort = 0 def main(): global udpSocket global destIp global destPort destIp = input("对方的IP:") destPort = int(input("对方的Port:")) udpSocket = socket(AF_INET,SOCK_DGRAM) udpSocket.bind(("",4567))#这里写两个()的缘由是将("",4567)当作一个总体元组使用
 tr = Thread(target = receiveInfo) ts = Thread(target = sendInfo) tr.start() ts.start() tr.join() ts.join() if __name__ == '__main__': main()

Mac电脑上执行程序以下:

windows电脑上运行网络调试助手以下:

从而就是实现了基于socket的udp的聊天功能。

9、udp应用:多线程聊天室的实现

程序基本流程:建立接收端socket ---> 建立发送到socket ---> 启动接收端socket ---> 启动发送端socket ---> 等待用户输入 ---> 接收用户输入并发送到广播 ---> 接收信息并显示。

# -*- coding:utf-8 -*-
from socket import *
from time import ctime, sleep import threading class ChatRoomPlus: def __init__(self): # 全局参数配置
        self.encoding = "utf-8"  # 使用的编码方式
        self.broadcastPort = 7788   # 广播端口

        # 建立广播接收器
        self.recvSocket = socket(AF_INET, SOCK_DGRAM) self.recvSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) self.recvSocket.setsockopt(SOL_SOCKET, SO_BROADCAST, 1) self.recvSocket.bind(('', self.broadcastPort)) # 建立广播发送器
        self.sendSocket = socket(AF_INET, SOCK_DGRAM) self.sendSocket.setsockopt(SOL_SOCKET, SO_BROADCAST, 1) # 其余
        self.threads = [] def send(self): """发送广播"""

        print("UDP发送器启动成功...") self.sendSocket.sendto("***加入了聊天室".encode(self.encoding), ('255.255.255.255', self.broadcastPort)) while True: sendData = input("请输入须要发送的消息:") self.sendSocket.sendto(sendData.encode(self.encoding), ('255.255.255.255', self.broadcastPort)) # print("【%s】%s:%s" % (ctime(), "我", sendData))
 sleep(1) def recv(self): """接收广播"""

        print("UDP接收器启动成功...") while True: # 接收数据格式:(data, (ip, port))
            recvData = self.recvSocket.recvfrom(1024) print("【%s】[%s : %s] : %s" % (ctime(), recvData[1][0], recvData[1][1], recvData[0].decode(self.encoding))) sleep(1) def start(self): """启动线程""" t1 = threading.Thread(target=self.recv) t2 = threading.Thread(target=self.send) self.threads.append(t1) self.threads.append(t2) for t in self.threads: t.setDaemon(True) t.start() while True: pass


if __name__ == "__main__": demo = ChatRoomPlus() demo.start()

运行效果:

Mac电脑上运行

linux电脑上运行程序

windows上运行程序

原文出处:https://www.cnblogs.com/Se7eN-HOU/p/10742148.html

相关文章
相关标签/搜索