python socket基础使用

184 阅读4分钟

1. TCP连接

1.1 服务端

  1. 导入socket模块
  2. socket创建一个套接字
  3. bind绑定ip和port
  4. listen使套接字设置为被动模式
  5. accept等待客户端的链接
  6. recv/send接收发送数据
# 1.导入socket模块
from socket import *

# 2.创建socket套接字 fun: socket.socket()
#                  parameter1:地址簇family: AddressFamily
#                        AF_INET  为 IPv4
#                        AF_INET6 为 IPv6
#                  parameter2:协议类型type:SocketKind
#                        SOCK_STREAM 为 TCP
#                        SOCK_DGRAM  为 UDP
tcp_server_socket = socket(AF_INET, SOCK_STREAM)

# 3.绑定ip和port    fun: socket.bind()
#                  parameter:address: tuple:("ip",port)
#   ip地址内容限制访问本机的网段  "127.0.0.1"     只有电脑本机的客户端,才能访问
#                             "192.168.38.217" 我在局域网内被分配到的ip地址,局域网内客户端均可连接
#                             
#   可以填空字符串,允许所有网卡都能够访问
tcp_server_socket.bind(("",1234))

# 4.服务端需将套接字设置为被动模式 fun: socket.listen()
#                             parameter: 指定 等待 客户端最大个数,此参数仅在windows下生效,其他系统不限制;等待:指服务端会缓存其他客户端的数据
tcp_server_socket.listen(128)
print("---------------此刻服务器已经开启,等待客户端链接----------------")

# 5. 等待客户端连接 fun: socket.accept()
tcp_client, client_addr = tcp_server_socket.accept()
#    tcp_client 为 连接的客户端对象,通过此对象 向客户端 传数据 和 接收数据
#    client_addr为 此客户端对象的 地址
print("----------有新的客户端已经连进来了:", client_addr, "-------------")

# 6. 使用recv接收数据时,会阻塞当前进程,直到接收到客户端的数据
client_data = tcp_client.recv(2048) # 接收2048个字节
#    服务器回复客户端消息 String.encode() parameter默认"utf-8",可选"GBK"
tcp_client.send("消息\0已\n收到".encode("utf-8")) 

# 7. 关闭服务器套接字 fun: socket.close()
tcp_server_socket.close()

1.2 客户端

  1. 导入socket模块
  2. 创建socket套接字
  3. 建立tcp连接(和服务端建立连接)
  4. 开始发送数据(到服务端)
  5. 关闭套接字
# 1. 导入socket模块
import socket

# 2. 创建socket套接字 fun: socket.socket()
#                   parameter1:地址簇family: AddressFamily
#                        AF_INET  为 IPv4
#                        AF_INET6 为 IPv6
#                   parameter2:协议类型type:SocketKind
#                        SOCK_STREAM 为 TCP
#                        SOCK_DGRAM  为 UDP
tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 3. 建立tcp连接(和服务端建立连接)fun: socket.connect()
#                              parameter:address: tuple:("ip",port)
tcp_client_socket.connect(("127.0.0.1",1234)) # 客户端的ip地址及端口号

# 4. 开始发送数据(到服务端)fun: socket.send()
#                        parameter: 编码后的数据
#                         String.encode() parameter默认"utf-8",可选"GBK"
tcp_client_socket.send("你好,hello".encode("UTF-8")) # 不能直接发字符串,必须经过编码

# 5. 关闭套接字 fun
tcp_client_socket.close()

2. UDP连接

2.1 发送端

  1. 导入模块socket
  2. 创建socket套接字
  3. 绑定IP&端口(可选)
  4. 发送数据
  5. 关闭套接字
# 1. 导入模块socket
import socket

# 2.创建socket套接字 fun: socket.socket()
#                  parameter1:地址簇family: AddressFamily
#                        AF_INET  为 IPv4
#                        AF_INET6 为 IPv6
#                  parameter2:协议类型type:SocketKind
#                        SOCK_STREAM 为 TCP
#                        SOCK_DGRAM  为 UDP
tcp_server_socket = socket(AF_INET, SOCK_DGRAM)

# 3. 绑定IP&端口(可选)
# udp_socket.bind(("", 3333)) 如果不使用bind(),接收端可以接收数据,但识别不到发送端的ip及端口
udp_socket.bind(("", 3333))
# 4. 发送数据 fun: socket.sendto()
#            parameter1:String.encode(),编码后的 要发送的字符串
#            parameter2:tuple("ip",port),元组(ip地址字符串,端口号)
data = "你好".encode("UTF-8")
addr = ("127.0.0.1", 8888)
udp_socket.sendto(data, addr)

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

socket.bind()

# 3. 绑定IP&端口(可选)
# udp_socket.bind(("", 3333)) # 未绑定     本机ip + 随机端口
udp_socket.bind(("", 3333))   # 绑定端口   本机ip + 固定端口
udp_socket.bind(("192.168.38.217", 3333)) # 绑定ip及端口

2.2 接收端

  1. 导入模块socket
  2. 创建socket套接字
  3. 绑定端口号(必选)
  4. 接收数据
  5. 关闭套接字
# 1. 导入模块socket
import socket

# 2. 创建socket套接字fun: socket.socket()
#                  parameter1:地址簇family: AddressFamily
#                        AF_INET  为 IPv4
#                        AF_INET6 为 IPv6
#                  parameter2:协议类型type:SocketKind
#                        SOCK_STREAM 为 TCP
#                        SOCK_DGRAM  为 UDP
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# 3. 绑定端口号(必选)
udp_socket.bind(("", 8888)) # 端口号要与发送端 发送数据时填写的端口号一致

# 4. 接收数据  fun: socket.recvfrom()
#             parameter: 缓冲区大小,
#             retuen tuple(parameter1, parameter2) 
#                    例:元组 (b'abc123\xd6\xd0', ('127.0.0.1', 3333))
#.                   parameter1: 字节数组类型的数据
#                    parameter2: 发送者的元组类型数据(IP,port)
# 代码会阻塞在这里,直到收到数据,释放阻塞
data, address = udp_socket.recvfrom(2048) # 大小自定,最大 一次性接收2048字节的数据(64K),没有收够2048个数据也可以

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

3. UDP广播

3.1 发送端

  1. 导入模块socket
  2. 创建socket套接字
  3. 设置允许发送广播
  4. 发送广播数据(注意广播地址)
  5. 关闭套接字
# 1. 导入模块socket
import socket

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

# 3. 设置允许发送广播 fun: socket.setsockopt()
#                  parameter1 __level:   设置的影响范围: SOL_SOCKET只针对当前socket对象
#                  parameter2 __optname: 要配置的属性名 SO_BROADCAST 广播
#                  parameter3 __value:   要配置的属性值 True 允许
udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, True)

# 可使用bind(),给发送端绑定一个ip及端口;未绑定则使用本机ip及随机端口

# 4. 发送广播数据(注意广播地址)
data = "Every Body Come On!".encode("utf-8")
udp_socket.sendto(data, ("192.168.38.255", 8888)) # 这里是广播地址

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

子网掩码:0xffffff00 == 255.255.255.0 有 24 个 1

掩码位: 24

广播ip: 192.168.38.255

广播可用: