一、socket(套接字)
1、理解socket:是应用层与TCP协议族通信的中间软件抽象层,他是一组接口。组织数据,以符号制定的协议。
2、家族:
1、AF_UNIX(文件类型的套接字家族):基于文件系统间接完成通信;
2、AF_INET(基于网络类型的套接字家族):基于网络完成通信;
3、python socket模块的使用
1、tcp socket:
端口复用:server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
2、udp socket:
创建udp_socket:udp_server=socket.socket(socket.AF_UNIX,socket.SOCK_DGRAM)
4、subprocess
res=subprocess.Popen(
cmd.decode('utf-8'),
shell=True,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
取值:res.stdout.read().decode()
5、粘包现象:udp永远不会粘包,只有TCP会粘包
成因:1.从表面上看,黏包问题主要是因为发送方和接收方的缓存机制、tcp协议面向流通信的特点。
2.实际上,主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的
6、解决粘包现象
1、每次把数据的大小发给接收端。
2、struct模块使用
struct.pack('i',数据包大小) 打包成四个字节的b'类型,给接收端接收;
struct.unpack('i',4字节的b') 解析出数据包的大小,根据这个大小接收数据

server=socket.socket()
server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
server.bind(('127.0.0.1',8080))
server.listen()
conn,addr=server.accept()
from_client_msg=conn.recv(1024)
print(from_client_msg)
conn.send(b'ok')
conn.close()
server.close()
tcp 服务端

import socket
client=socket.socket()
client.connect(('127.0.0.1', 8080))
client.send(b'zaima')
from_client_msg=client.recv(1024)
print(from_client_msg)
client.close()
tcp客户端

import socket
udp_server=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
udp_server.bind(('127.0.0.1',8080))
while 1:
qq_msg,addr=udp_server.recvfrom(1024)
if not qq_msg:
continue
else:
qq_msg=qq_msg.decode('utf-8')
print(f"来自addr:{addr[0]}port:{addr[1]}的信息>>>",qq_msg)
msg=input(">>>客户端").encode("utf-8")
udp_server.sendto(msg,addr)
udp 服务端

import socket
#创建qq对象
qq_name_addr={
'金老板':('127.0.0.1',8080),
'alex':('127.0.0.1',8080),
'wusir':('127.0.0.1',8080)
}
udp_client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
flag=1
while flag:
qq_obj=input('请选择你要聊天的对象')
while 1:
if qq_obj not in qq_name_addr:
print("输入错误,请重新选择对象")
break
elif qq_obj.upper()=="Q":
flag=0
break
else:
udp_client_msg=input(f'给{qq_obj}说的心里话>>>').strip()
if udp_client_msg.upper()=='Q':
flag=0
break
else:
udp_client.sendto(udp_client_msg.encode(),qq_name_addr[qq_obj])
from_server_msg,addr=udp_client.recvfrom(1024)
print(from_server_msg.decode('utf8'))
udp 客服端

import subprocess
cmd_msg=input('请输入CMD命令').strip()
obj=subprocess.Popen(
cmd_msg,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
print(obj.stdout.read().decode('gbk'))
print(obj.stderr.read().decode('gbk'))
subprocess

import socketserver
class Myserver(socketserver.BaseRequestHandler):
def handle(self):
self.request.recv(1024)
msg = '亲,你学会了码?'
self.request.send(msg.encode('utf-8'))
self.request.close()
if __name__ == '__main__':
server = socketserver.ThreadingTCPServer(('127.0.0.1', 8080), Myserver)
server.serve_forever()
socketserver 服务端

import socket
client=socket.socket()
client.connect(('127.0.0.1',8080))
client.send(b'ko')
from_ser_msg=client.recv(1024)
print(from_ser_msg.decode('utf-8'))
socketserver 客户端