Python-简单的套接字通信
一、socket
什么是socket
socket是用于在两个基于TCP/IP协议的应用程序之间相互通信。最早出现在UNIX系统中,是UNIX系统主要的信dao息传递方式。在WINDOWS系统中,SOCKET称为WINSOCK。
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
所以,我们无需深入理解tcp/udp协议,socket已经为我们封装好了,我们只需要遵循socket的规定去编程,写出的程序自然就是遵循tcp/udp标准的。
简单来讲,Socket是网络应用程序接口,是应用层到传送层的接口。也就是用户进程,与系统内核的接口。
二、基于tcp协议实现简单套接字通信
将套接字通信比喻为手机通信,那么我们现在有客户端与服务端两个部分。
客户端
1.大家都需要买手机,即创建一个socket对象。
2.对于客户端来说,有了手机(socket对象之后)就可以拨打电话了,我们需要知道电话号码,即对方的ip地址与端口号,因为ip地址+端口号可以标记世界上独一无二的一个软件。127.0.0.1表示本地回环地址,一般在自己测试的时候使用,防止外部人员的干扰。
3.拨打完电话之后就可以开始通话了,即传输内容,因为我们不可能说一句话就结束通话,所以使用循环。
4.在结束通话后,我们需要关闭手机。回收资源
# 客户端
import socket
# 1、买手机
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # SOCK_STREAM=》TCP协议
# 2、拨电话
phone.connect(("127.0.0.1", 8080))
# 3、发/收消息=>通信循环
while True:
msg = input(">>: ").strip()
phone.send(msg.encode('utf-8'))
data = phone.recv(1024)
print("服务端返回的数据:", data.decode('utf-8'))
# 4、关闭
phone.close()
服务端
1.无论是客户端还是服务端,都需要一个手机,创建一个socket对象。
2.服务端需要声明自己的手机号码,让客户打过来。即确定自己的ip地址与端口号
3.开机,设定半连接池的大小。
4.等客户电话,若有电话打进来我们需要先接通,即conn, client_addr = phone.accept()
5.开始通信
6.通信结束,应该先挂断电话,即conn.close()
7.关闭手机,回收资源
"""
服务端应该满足的特性:
1、一直对外提供服务
2、并发地提供服务
"""
import socket
# 1、买手机
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # SOCK_STREAM=》TCP协议
# 2、插手机卡
phone.bind(("127.0.0.1", 8080)) # 本地回环
# 3、开机
phone.listen(5)
print('starting %s:%s' %("127.0.0.1", 8080))
# 4、等电话链接=>链接循环
while True:
conn, client_addr = phone.accept()
print(client_addr)
# 5、收/发消息=>通信循环
while True:
try:
data = conn.recv(1024) # 最大接收的字节个数
if len(data) == 0: # 针对linux系统
break
print("收到的客户端数据:", data.decode('utf-8'))
conn.send(data.upper())
except Exception: # 针对windows系统
break
# 6、关闭
conn.close() # 挂电话
phone.close() # 关机
远程执行命令(简易版)
服务端
"""
服务端应该满足的特性:
1、一直对外提供服务
2、并发地提供服务
"""
import socket
import subprocess
# 1、买手机
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # SOCK_STREAM=》TCP协议
# 2、插手机卡
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 就是它,在bind前加
phone.bind(("127.0.0.1", 8080)) # 本地回环
# 3、开机
phone.listen(5)
print('starting %s:%s' % ("127.0.0.1", 8080))
# 4、等电话链接=>链接循环
while True:
conn, client_addr = phone.accept()
print(client_addr)
# 5、收/发消息=>通信循环
while True:
try:
cmd = conn.recv(1024) # 最大接收的字节个数
if len(cmd) == 0: # 针对linux系统
break
obj = subprocess.Popen(cmd.decode('utf-8'),
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
res=obj.stdout.read()+obj.stderr.read() # ???
print(res)
conn.send(res)
except Exception: # 针对windows系统
break
# 6、关闭
conn.close() # 挂电话
phone.close() # 关机
客户端
import socket
# 1、买手机
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # SOCK_STREAM=》TCP协议
# 2、拨电话
phone.connect(("127.0.0.1", 8080))
# 3、发/收消息=>通信循环
while True:
cmd = input("[root@localhost]# ").strip()
phone.send(cmd.encode('utf-8'))
data = phone.recv(1024)
print(data.decode('gbk'))
# 4、关闭
phone.close()