3:UDP-发送、接收数据及多线程版UDP聊天器

UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768是UDP的正式规范。

根据OSI(开放系统互连)参考模型,UDP和TCP都属于传输层协议。UDP协议的主要作用是将网络数据流量压缩成数据包的形式。一个典型的数据包就是一个二进制数据的传输单位。每一个数据包的前8个字节用来包含报头信息,剩余字节则用来包含具体的传输数据。

一、UDP 网络程序 - 发送数据

1.1、发送数据的流程

创建套接字

发送数据

关闭套接字

1.2、创建udp的套接字

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

1.3、输入套接字发送的内容

send_data = input("请输入发送的内容:")

1.4、发送套接字内容

第一个参数是:发送的内容; 内容要是byte类型,用utf-8转一下

第二个参数是元组类型,元组内两个参数,第一个是:对方的ip地址,第二个是对方的port(端口)

udp_socket.sendto(send_data.encode('utf-8'),("192.168.3.6",8080))

1.5、发送完内容关闭套接字

udp_socket.close()

1.6、完整的udp套接字发送代码(可以把 2 的内容放到while True:循环里面,一直发送数据)

提示:同一台电脑不允许有两个相同的端口,发送端如果不设置端口,电脑就会随机分配端口

二、UDP 网络程序 - 接收数据

2.1、接收数据的流程

创建套接字

绑定本地自己的信息(ip和自己设置的port)

接收数据

关闭套接字

2.2、创建套接字

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

2.3、绑定本地自己的信息(ip和自己设置的port)

localaddr = ("",6688) # ip一般不用写,表示本机的任何一个ip,"192.168.3.6"

udp_socket.bind(localaddr) # 必须绑定自己电脑的ip和port,其他的电脑不行

2.4、接收数据(Windows解码是用 dbk,想要一直接收数据,可以把内容放到while True:循环里面,一直接收数据)

# 3.1、接收内容(参数是允许接收的最大内容)

receive_data = udp_socket.recvfrom(1024)

# 3.2、接收的内容分为两部分:一部分是 存储的时候接收的数据,另一部分是发送方的ip和port

receive_message = receive_data[0] # 存储接收的数据

receive_addr = receive_data[1] # 存储发送方的地址信息

print("内容=%s : 对方的信息=%s"%(str(receive_addr),receive_message.decode("utf-8")))

2.5、关闭套接字

udp_socket.close()

提示:同一台电脑不允许有两个相同的端口,接收方必须设置端口,

网络通信过程中,之所需要ip、port等,就是为了能够将一个复杂的通信过程进行任务划分,从而保证数据准确无误的传递

三、一个简单的UDP聊天器

3.1、需求:在一个电脑中编写1个程序,有2个功能

1、获取键盘数据,并将其发送给对方

2、接收数据并显示,并且功能数据进行选择以上的2个功能调用

3.2、代码实现

import socket

def sent_message(udp_socket):

      """发送消息"""

      # 2、让用户输入对方的IP和端口号

      dest_ip = input("请输入对方的ip:")

      try:

        dest_port = input("请输入对方的port:")

      except:

        print("请输入正确的端口号")

      # 3、从键盘获取要发送的数据

      send_data = input("请输入要发送的内容:")

    # 4、用套接字发送内容

    udp_socket.sendto(send_data.encode('utf-8'),(dest_ip,dest_port))

def receive_message(udp_socket):

        """接收消息"""

        # 2、使用 udp_socket 套接字就接收数据,接收内容(参数是允许接收的最大内容)

        receive_data = udp_socket.recvfrom(1024)

        # 3、接收的内容分为两个部分:

        # 一部分是:对方发送的内容

        # 另一部分是:对方的本地信息

        receive_content = receive_data[0].decode('utf-8') # 存储接收的数据

        receive_localAddr = receive_data[1] # 对方的本地信息

        print("%s:%s"%(receive_content,receive_localAddr))

def main():

      """主函数:聊天神器"""

      # 1、创建udp套接字

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

      # 2、绑定一个本地的信息

      local_addr = ("",7777)

      udp_socket.bind(local_addr) # 必须绑定自己电脑的ip和port,其他的电脑不行

      # 3、功能选择

      print("欢迎使用UDP聊天神器")

      # 用循环来处理事情

      while True:

          print("1:发送消息\n2:接收消息")

          input_str = input("请输入选择的功能:")

          if input_str == "1":

                # 发送数据

                sent_message(udp_socket)

          elif input_str == "2":

                # 接收数据

                receive_message(udp_socket)

          elif input_str == "0":

                # 退出程序

                break

          else:

              print("请输入正确的功能")

      # 4、关闭套接字

      udp_socket.close()

if __name__ == "__main__":

        main()

提示:以上的程序如果选择了接收数据功能,并且此时没有数据,程序会堵塞在这,那么怎样才能让这个程序收发数据一起进行呢?采用多线程多任务知识就解决

3.3 多线程版UDP

多线程版UDP聊天器


6.1、流程

创建套接字

绑定本地信息

输入对方的ip与端口

创建子线程进行发送和接收数据

6.2、具体的代码

import socket

import threading

def receive_message(udp_socket):

        """接收消息"""

      while True:

            receive_data = udp_socket.recvfrom(1024)

            print("接收的内容是:%s"%receive_data[0].decode("utf-8"))

def send_message(udp_socket,other_ip,other_port):

        """发送消息"""

      while True:

            send_data = input("请输入发送的内容:")

            udp_socket.sendto(send_data.encode("utf-8"),(other_ip,other_port))

            print("你发的内容是:%s" % send_data)

def main():

      # 1、创建

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

      # 2、绑定本地端口信息

      local_addr = ("192.168.3.230",7990)

      udp_socket.bind(local_addr)

      # 3、输入对方的IP与端口号

      other_ip = input("请输入对方的ip:")

      other_port = int(input("亲输入对方的端口号port:"))

      # 4、创建2个子线程用来 发送消息 和 接收消息

      thread_send = threading.Thread(target=send_message,args=(udp_socket,other_ip,other_port))

      thread_receive = threading.Thread(target=receive_message,args=(udp_socket,))

      thread_send.start()

      thread_receive.start()

if __name__ == '__main__':

      main()

四、拓展:通信中的:单工、半工、全双工

单工:表面意思就是单项的操作,其实就是通信的单项传输,如收音机,你只能接收数据

半双工:是既可以发送数据,也可以接收数据,但是二者不能同时进行,如:对讲机,对方说完话,你才可以听到,他说的内容

全双工:发送内容与接收内容是可以同步进行的,如:电话,我们可以听着别人的话,也可以说出话,同时进行

作者:IIronMan

链接:https://www.jianshu.com/p/e02d3f7640b6

链接:https://www.jianshu.com/p/484114fe80c9(多线程版UDP聊天器)

来源:

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

你可能感兴趣的:(3:UDP-发送、接收数据及多线程版UDP聊天器)