五层协议 : 从传输层包括传输层以下 , 都是操作系统帮我们封装的各种head
socket套接字充当的就是内置模块的角色
socket 套接字,它存在于传输层与应用层之间的抽象层
避免你学习各层的接口以及协议的使用, socket已经封装好了所有的接口 .
直接使用这些接口或者方法即可 , 使用起来方便,提升开发效率
socket 就是一个模块 , 通过使用学习模块提供的功能 , 建立客户端与服务端的通信
套接字的工作流程(基于TCP和 UDP两个协议) TCP协议下的socket socket()模块函数用法 import socket socket.socket(socket_family,socket_type,protocal=0) socket_family 可以是 AF_UNIX 或 AF_INET。socket_type 可以是 SOCK_STREAM 或 SOCK_DGRAM。protocol 一般不填,默认值为 0。 # 获取tcp/ip套接字 tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) tcpSock = socket.socket() # 括号里可以不写 默认 # 获取udp/ip套接字 udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 由于 socket 模块中有太多的属性。我们在这里破例使用了\'from module import *\'语句。使用 \'from socket import *\',我们就把 socket 模块里的所有属性都带到我们的命名空间里了,这样能 大幅减短我们的代码。 例如tcpSock = socket(AF_INET, SOCK_STREAM) ##============服务端套接字函数 s.bind() # 绑定(主机,端口号)到套接字 s.listen() # 开始TCP监听 s.accept() # 被动接受TCP客户的连接,(阻塞式)等待连接的到来 ##============客户端套接字函数 s.connect() # 主动初始化TCP服务器连接 s.connect_ex() connect()函数的扩展版本,出错时返回出错码,而不是抛出异常 ##============公共用途的套接字函数 s.recv() # 接收TCP数据 s.send() # 发送TCP数据(send在待发送数据量大于己端缓存区剩余空间时,数据丢失,不会发完) s.sendall() 发送完整的TCP数据(本质就是循环调用send,sendall在待发送数据量大于己端缓存区剩余空间时,数据不丢失,循环调用send直到发完) s.recvfrom() 接收UDP数据 s.sendto() 发送UDP数据 s.getpeername() 连接到当前套接字的远端的地址 s.getsockname() 当前套接字的地址 s.getsockopt() 返回指定套接字的参数 s.setsockopt() 设置指定套接字的参数 s.close() # 关闭套接字 面向锁的套接字方法 s.setblocking() 设置套接字的阻塞与非阻塞模式 s.settimeout() 设置阻塞套接字操作的超时时间 s.gettimeout() 得到阻塞套接字操作的超时时间 面向文件的套接字的函数 s.fileno() 套接字的文件描述符 s.makefile() 创建一个与该套接字相关的文件 第一版 单个客户端与服务端通信(low版) # server端 import socket phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 创建socket 对象 phone.bind((\'127.0.0.1\',8080)) # 8000 ~ 65535 绑定ip地址和端口 phone.listen(5) # TCP 开始监听 # conn相当于管道 conn, client_addr = phone.accept() # 被动接受TCP客户的连接,(阻塞式)等待连接的到来 print(conn, client_addr, sep=\'\n\') # 打印通道 和 客户端的地址 from_client_data = conn.recv(1024) # 每次 接收 客户端内容 的 最大限制 1024 bytes print(from_client_data.decode(\'utf-8\')) conn.send(from_client_data.upper()) # 向客户端发送 信息 conn.close() # 挂电话 phone.close() # 关闭套接字 # client import socket phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 买电话 phone.connect((\'127.0.0.1\',8080)) # 与客户端建立连接, 拨号 phone.send(\'hello\'.encode(\'utf-8\')) from_server_data = phone.recv(1024) print(from_server_data.decode(\'utf-8\')) phone.close() # 挂电话 第二版,通信循环 # server import socket photo = socket.socket() photo.bind((\'127.0.0.1\',8080)) phone.listen(5) conn, client_addr = phone.accept() print(conn, client_addr, sep=\'\n\') while 1: # 循环收发消息 try: from_client_data = conn.recv(1024) print(from_client_data.decode(\'utf-8\')) conn.send(from_client_data + b\'SB\') except ConnectionResetError: break conn.close() phone.close() # client import socket phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 买电话 phone.connect((\'127.0.0.1\',8080)) # 与客户端建立连接, 拨号 while 1: # 循环收发消息 client_data = input(\'>>>\') phone.send(client_data.encode(\'utf-8\')) from_server_data = phone.recv(1024) print(from_server_data.decode(\'utf-8\')) phone.close() # 挂电话 第三版 通信 / 连接循环 *** # server import socket phone = socket.socket() phone.bind((\'127.0.0.1\', 8080)) phone.listen(5) while 1: # 循环连接客户端 conn, client_addr = phone.accept() print(conn,client_addr) while 1: try: from_client_data = conn.recv(1024) print(from_client_data.decode(\'utf-8\')) conn.send(from_client_data + b\'SB\') except ConnectionResetError: break conn.close() phone.close() # client import socket phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 买电话 phone.connect((\'127.0.0.1\',8080)) # 与客户端建立连接, 拨号 while 1: client_data = input(\'>>>\') phone.send(client_data.encode(\'utf-8\')) from_server_data = phone.recv(1024) print(from_server_data.decode(\'utf-8\')) phone.close() # 挂电话 远程执行命令的示例 # server import socket import subprocess phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM) phone.bind((\'127.0.0.1\',8080)) phone.listen(5) while 1 : # 循环连接客户端 conn, client_addr = phone.accept() print(client_addr) while 1: try: cmd = conn.recv(1024) ret = subprocess.Popen(cmd.decode(\'utf-8\'),shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) correct_msg = ret.stdout.read() error_msg = ret.stderr.read() conn.send(correct_msg + error_msg) except ConnectionResetError: break conn.close() phone.close() # client import socket phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 买电话 phone.connect((\'127.0.0.1\',8080)) # 与客户端建立连接, 拨号 while 1: cmd = input(\'>>>\') phone.send(cmd.encode(\'utf-8\')) from_server_data = phone.recv(1024) print(from_server_data.decode(\'gbk\')) phone.close() # 挂电话 粘包 粘包概念粘包只会出现在tcp传输中, 是两种不同的数据连接在一起无法正常分离,就会出现粘包
粘包现象