• 使用 python socket 实现UDP/TCP网络通信


    目录

    目录

    1.socket简介

    2.创建socket

    2.1创建UDPSocket

    2.2创建TCPSocket

    3.使用UDPSocket发送数据并接收

    4.使用UDPSocket发送广播

    5.UDPSocket聊天器 (多线程实现消息的收发功能)

    6.使用TCPSocket建立客户端

    7.使用TCPSocket建立服务端


    1.socket简介

           socket(简称:套接字),是支持TCP和UDP(网络传输方式网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程。

            它能实现不同主机间的进程间通信,我们网络上各种各样的服务大多都是基于socket来完成通信的,例如浏览的网页、qq聊天、收发email等等。

    2.创建socket

            socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,对于文件用打开、读写、关闭模式来操作。socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket类就是对其进行的操作(读写IO、打开、关闭)

    在Python中使用socket模块的socket类来完成:

    1. import socket
    2. socket.socket(AddressFamily, Type)

    说明:

            1. 参数:AddressFamily(地址簇)

            socket.AF_INET IPv4          (默认)       

            socket.AF_INET6 IPv6

            socket.AF_UNIX                    只能够用于单一的Unix系统进程通信

            2.参数:Type(类型)

            socket.SOCK_STREAM        流式socket,for TCP(默认)

            socket.SOCK_DGRAM         数据报式socket,for UDP

    2.1创建UDPSocket

    1. import socket
    2. # 使用IPv4 UDP方式来创建套接字
    3. udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) # 参数socket.AF_INET表示使用IPv4,参数socket.SOCK_DGRAM表示使用UDP
    4. # 省略数据传递过程
    5. # 关闭套接字
    6. udp_socket.close()

    2.2创建TCPSocket

    1. import socket
    2. # 使用IPv4 TCP方式来创建套接字
    3. tcp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 参数socket.AF_INET表示使用IPv4,参数socket.SOCK_STREAM表示使用TCP
    4. # 省略数据传递过程
    5. # 关闭套接字
    6. tcp_socket.close()

    3.使用UDPSocket发送数据并接收

    核心方法:

            socket.sendto

    sendto方法的参数:

            1.要发送的二进制数据        (使用.encode()方法可以将字符串转为二进制)

            2.接收者的ip地址和端口号  (元组类型:("127.0.0.1", 8080))

    1. import socket
    2. # 使用IPv4 UDP方式来创建套接字
    3. udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    4. #2.绑定一个本地信息
    5. localaddr = ("192.168.68.196",8081)
    6. udp_socket.bind(localaddr)
    7. # 发送数据
    8. udp_socket.sendto("hello".encode(),("192.168.68.196",8080))
    9. # 关闭套接字
    10. udp_socket.close()

    接收数据(两种方式):

            方式一:通过网络调试助手接收(下载地址:NetAssist.exe下载

    对于接收到的中文是乱码的问题:

            可能是由于encode()方法默认使用UTF-8的编码方式

    .encode()

     将其改为gb2312编码方式:

    .encode("gb2312")

    如下图标注部分为修改编码方式前后的对比: 

            方式二:通过python代码制作一个接收端

    1. import socket
    2. def main():
    3. #1.创建套接字
    4. udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    5. #2.绑定一个本地信息
    6. localaddr = ("192.168.68.196",8080)
    7. udp_socket.bind(localaddr)
    8. #3.接收数据
    9. while True:
    10. recv_data = udp_socket.recvfrom(1024) #1024表示每次接收1024字节
    11. recv_msg = recv_data[0] #存储接收到的数据
    12. send_addr = recv_data[1]#存储发送方的地址信息
    13. #4.打印接收到的数据
    14. # print(recv_data)
    15. print("%s:%s" % (str(send_addr),recv_msg.decode("gb2312")) )
    16. #5.关闭套接字
    17. udp_socket.close()
    18. if __name__ == "__main__":
    19. main()

    4.使用UDPSocket发送广播

            广播地址(Broadcast Address)是专门用于同时向网络中所有工作站进行发送的一个地址。在使用TCP/IP 协议的网络中,主机标识段host ID 为全1 的IP 地址为广播地址,广播的分组传送给host ID段所涉及的所有计算机。例如,对于10.1.1.0 (255.0.0.0 )网段,其广播地址为10.255.255.255 (255 即为二进制的11111111 ),当发出一个目的地址为10.255.255.255 的分组(封包)时,它将被分发给该网段上的所有计算机。

    1. import socket
    2. # 使用IPv4 UDP方式来创建套接字
    3. udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    4. #2.绑定一个本地信息
    5. localaddr = ("192.168.68.196",8081)
    6. udp_socket.bind(localaddr)
    7. # 设置允许发送广播
    8. udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, True)
    9. # 发送信息
    10. udp_socket.sendto("大家好,我宣布个事儿".encode("gb2312"), ("255.255.255.255", 8080))
    11. # 关闭套接字
    12. udp_socket.close()

    运行结果:(此时处于同一网段,端口为8080的客户端应该都能接收到广播信息)

    5.UDPSocket聊天器 (多线程实现消息的收发功能)

    实现效果:

    python UDPSocket聊天器 (多线程实现消息的收发功能)

    代码:

    1. import socket
    2. from threading import Thread,Lock
    3. def send_msg(udp_socket):
    4. """发送信息的函数"""
    5. while True:
    6. input_msg = input("请输入聊天内容:\n") # 用户输入一些信息
    7. udp_socket.sendto(input_msg.encode("gb2312"), ("192.168.68.196", 8081))
    8. def recv_msg(udp_socket):
    9. """接收信息的函数"""
    10. while True:
    11. recv_data, tuple_ip_port = udp_socket.recvfrom(1024)
    12. recv_text = recv_data.decode("gb2312")
    13. print("接受到[%s]的信息:%s" % (str(tuple_ip_port), recv_text))
    14. def main():
    15. # 创建套接字
    16. udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    17. # 绑定端口
    18. udp_socket.bind(("", 8080))
    19. # 接收信息
    20. t1 = Thread(target=recv_msg, args=(udp_socket,))
    21. t1.start()
    22. # 发送信息
    23. t2 = Thread(target=send_msg, args=(udp_socket,))
    24. t2.start()
    25. # # 关闭套接字
    26. # udp_socket.close()
    27. if __name__ == '__main__':
    28. main()

    6.使用TCPSocket建立客户端

    1. import socket
    2. # 创建套接字
    3. tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    4. # 建立连接
    5. tcp_client_socket.connect(("192.168.68.196", 8081))
    6. # 发送数据
    7. tcp_client_socket.send("你好".encode("gb2312"))
    8. # 接收数据
    9. recv_data = tcp_client_socket.recv(1024).decode("gb2312")
    10. print(recv_data)
    11. # 关闭套接字
    12. tcp_client_socket.close()

    7.使用TCPSocket建立服务端

            ·能够实现一个客户端发来的多条信息

            ·能够接收多个客户端连接

    1. import socket
    2. from threading import Thread
    3. def new_client_connect(new_client_socket, client_ip_port):
    4. while True:
    5. # 收发数据
    6. recv_data = new_client_socket.recv(1024)
    7. if len(recv_data) != 0:
    8. recv_text = recv_data.decode("gb2312")
    9. print("接收到[%s]的信息:%s" % (str(client_ip_port), recv_text))
    10. else:
    11. print("客户端断开连接")
    12. break
    13. # # 关闭连接
    14. # new_client_socket.close() # 表示断开与当前的客户端的通信
    15. def main():
    16. # 创建套接字
    17. tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    18. # 绑定端口和ip
    19. tcp_server_socket.bind(("", 8081))
    20. # 设置套接字为被动监听模式,不能主动发送数据,128为允许接收的最大连接数
    21. tcp_server_socket.listen(128)
    22. while True:
    23. # 接收客户端连接
    24. new_client_socket, client_ip_port = tcp_server_socket.accept()
    25. t1 = Thread(target=new_client_connect, args=(new_client_socket, client_ip_port))
    26. t1.start()
    27. # tcp_server_socket.close() # 表示不再接受新客户端的连接,已经连接的可以继续服务
    28. if __name__ == '__main__':
    29. main()

     效果:

    python TCPSocket服务器 (多线程实现消息的接收功能)

  • 相关阅读:
    数据结构-快速排序
    LeetCode-高频 SQL 50 题:连接 篇
    Python编程实例-播放音频汇总(Linux环境)
    docker安装Apache NIFI
    关于云主机root无法从VNC登录处理
    【C语言】字符函数和字符串函数(1)
    数据库范式理论
    Windows内核函数 - ANSI_STRING字符串与UNICODE_STRING字符串
    2023国赛数学建模E题思路代码 - 黄河水沙监测数据分析
    MIT 6.NULL The Missing Semester of Your CS Education(1)
  • 原文地址:https://blog.csdn.net/ChaoChao66666/article/details/126674607