1.socket是什么?
socket就是应用层与TCP/IP协议通信的中间软件抽象层,它是一组接口。
套接字分为两类:
基于文件类型的套接字家族:AF_UNIX
基于网络类型的套接字家族:AF_INET
127.0.0.1:本地回环地址,只能访问本机。
套接字工作流程:
socket()模块函数用法
import socket
scoket.scoket(socket_family, socket_type, protocal = 0)
# socket_family 可以是:AF_UNIX或AF_INET;socket_type 可以是SOCK_STREAM或SOCK_DGRAM;protoca一般不填,默认值为0.
#获取tcp/ip套接字
tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 获取udp/ip套接字
udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
服务端套接字函数
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.clsoe() 关闭套接字
基于TCP的套接字
tcp是基于链接的,必须先启动服务端,然后再启动客户端去链接服务端
最简单利用socket的 C/S实现
# client
import socket
client = socket.socket()
client.connect(('127.0.0.1',8080))
client.send(r'ARE YOU OKAY?')
date = client.recv(1024)
print(data)
client.close()
# server
import socket
server = socket.socket()
server.bind(('127.0.0.1', 8080))
server.listen(5)
conn ,addr = server.accept()
data = conn.recv(1024)
print(data)
conn.send(r'I am not okay')
conn.close()
server.close()
链接循环
# client
import scoket
import struct
import json
client = socket.socket()
client.connect(('127.0.0.1',8081))
while True:
msg = input('>>:').encode('utf-8')
if len(msg) == 0 :continue # 输入为空,直接跳过
client.send(msg)
header = client.revc(4)
header_len = struct.unpack('i', header)[0] # 对这个头进行解包,获取真实数据的长度 ,struck主要是用来处理C结构数据的
head_dic = json.loads(client.recv(head_len).decode('utf-8'))
print(head_dic)
total_size = head_dic['len']
recv_size = 0
res = b''
while recv_size < total_size:
data = client.recv(1024)
res +=data
recv_size += len(data)
print(res.decode('gbk'))
# server
import socket
import static
import json
import subprocess #即允许你去创建一个新的进程让其执行另外的程序,并与它进行通信,获取标准的输入、标准输出、标准错误以及返回码等
"""
服务端:
要有固定的ip和port
24小时不间断提供服务
"""
server = socket.socket()
server.bind(('127.0.0.1', 8081))
server.listen(5) # 半连接池
while True:
conn,addr = server.accpet() # 阻塞
while True:
try:
if len(data) == 0: break # 针对linux和mac系统 客户端异常断开反复收空的情况
obj = subprocess.Popen(data, shell = true, stdout = subprocess.PIPE,stderr = subprocess.PIPE)
stdout = obj.stdout.read()
stderr = obj.stderr.read()
print(len(stdout + stderr))
header_dic = {
'filename' : 'cls.av'
'len':len(stdout + stderr)
}
header_bytes = json.dumps(header_dic).encode('utf-8') # 制作报头
header = struct.pack('i', len(header_bytes)) # 将需要发送给客户端的数据打包成固定4个字节
conn.send(header)
conn.send(header_bytes)
conn.send(stdout + stderr)
except ConnectionResetError:
break
conn.close()
server.clsoe()