1. TCP连接
1.1 服务端
- 导入
socket模块 socket创建一个套接字bind绑定ip和portlisten使套接字设置为被动模式accept等待客户端的链接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 客户端
- 导入
socket模块 - 创建
socket套接字 - 建立tcp连接(和服务端建立连接)
- 开始发送数据(到服务端)
- 关闭套接字
# 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 发送端
- 导入模块socket
- 创建socket套接字
- 绑定IP&端口(可选)
- 发送数据
- 关闭套接字
# 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 接收端
- 导入模块socket
- 创建socket套接字
- 绑定端口号(必选)
- 接收数据
- 关闭套接字
# 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 发送端
- 导入模块socket
- 创建socket套接字
设置允许发送广播- 发送广播数据(注意广播地址)
- 关闭套接字
# 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
广播可用: