Loading

python网络编程-udp

1. 创建socket

在 Python 中 使用socket 模块的函数 socket 就可以完成(大多数的编程语言的套路是相似的):

import socket
socket.socket(AddressFamily, Type)

说明:

函数 socket.socket 创建一个 socket,该函数带有两个参数:

  • Address Family:可以选择 AF_INET(用于 Internet 进程间通信) 或者 AF_UNIX(用于同一台机器进程间通信),实际工作中常用AF_INET
  • Type:套接字类型,可以是 SOCK_STREAM(流式套接字,主要用于 TCP 协议)或者 SOCK_DGRAM(数据报套接字,主要用于 UDP 协议)

创建一个udp socket(udp套接字):

import socket

# 创建udp socket
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# ...
# 使用套接字收/发数据

# 关闭socket
udp_socket.close()

说明:

  • 套接字使用流程 与 文件的使用流程很类似
    1. 创建套接字
    2. 使用套接字收/发数据
    3. 关闭套接字

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

创建一个基于udp的网络程序流程很简单,具体步骤如下:

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

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

        # 读取输入的数据
        send_data = input('请输入要发送的数据:')

        # 发送数据
        send_addr = ('192.168.92.190', 7878)
        udp_socket.sendto(send_data.encode('GBK'), send_addr)

        # 关闭
        udp_socket.close()



if __name__ == '__main__':
        main()

在ubuntu的终端中执行:

在windows中运行“网络调试助手”:

3. udp网络程序-接收数据

import socket

def main():

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

        # 绑定一个本地信息
        localaddr = ("", 8080)
        udp_socket.bind(localaddr)

        # 接收数据
        recv_data = udp_socket.recvfrom(1024)

        # recv_data是一个元组(接收到的数据, (发送方的IP, port))
        recv_msg = recv_data[0] # 存储接收到的数据
        send_addr = recv_data[1] # 存储发送方的地址

        # 打印收到的消息
        # print(recv_data)
        print("%s:%s" % (str(send_addr), recv_msg.decode('GBK')))

        # 关闭
        udp_socket.close()

if __name__ == '__main__':
        main()
        

在ubuntu的终端中执行:

在网咯助手中发送数据:

4. python3中的编码转换

  • 使用socket发送的是数据的二进制,需要将字符串转换成bytes
str.encode()
  • 使用socket接收的是数据的二进制,需要将bytes转换成字符
bytes.decode()

在ipython3中尝试:

In [2]: text = "一串文本"

In [3]: text
Out[3]: '一串文本'

In [5]: bytes_text = text.encode()

In [6]: bytes_text
Out[6]: b'\xe4\xb8\x80\xe4\xb8\xb2\xe6\x96\x87\xe6\x9c\xac'

In [7]: type(text)
Out[7]: str

In [8]: type(bytes_text)
Out[8]: bytes

In [9]: decoded_text = bytes_text.decode()
    
In [10]: decoded_text
Out[10]: '一串文本'

其中decode()与encode()方法可以接受参数,其声明分别为:

bytes.decode(encoding="utf-8", errors="strict")
str.encode(encoding="utf-8", errors="strict")

其中的encoding是指在解码编码过程中使用的编码(此处指“编码方案”是名词),errors是指错误的处理方案。

详细的可以参照官方文档:

5. udp端口绑定

  • 一个udp网络程序,运行时没有绑定端口,系统会给它分配一个随机的端口,如果再次运行,端口可能发生变化
  • 一个udp网络程序,也可以绑定信息(ip地址,端口号),如果绑定成功,那么操作系统用这个端口号来进行区别收到的网络数据是否是此进程的

什么时候需要绑定端口呢?

一般来说,如果要做成一个服务端的应用程序的话,是需要绑定固定端口的。

posted @ 2018-12-05 22:58  coder-qi  阅读(1475)  评论(0编辑  收藏  举报