本节内容
- Socket介绍
- 参数介绍
- 基本实例
- Socket实现多连接处理
- 通过Socket实现简单SSH
- 通过Socket实现文件传送
Socket网络编程
此部分内容涉及到 计算机网络相关知识
OSI七层网络模型
- 大概的流程如下:
通信实例
消息的发送和接收
#Author:yyqian
#客户端
import socket
client = socket.socket() #声明socket类型,同时生成socket连接对象
client.connect(('localhost',6969))
while True:
msg = input(">>:").strip()
if len(msg) == 0:continue
client.send(msg.encode("utf-8"))
data = client.recv(10240)
print("recv:",data.decode())
client.close()
#Author:yyqian
#服务器端
import socket
server = socket.socket()
server.bind(('localhost',6969)) #绑定要监听端口
server.listen(5) #监听
print("我要开始等电话了")
while True:
conn, addr = server.accept() # 等电话打进来
# conn就是客户端连过来而在服务器端为其生成的一个连接实例
print(conn, addr)
print("电话来了")
count = 0
while True:
data = conn.recv(1024)
print("recv:",data)
if not data:
print("client has lost...")
break
conn.send(data.upper())
count+=1
if count >10:break
server.close()
结果
server端:
我要开始等电话了
<socket.socket fd=368, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 6969), raddr=('127.0.0.1', 3206)> ('127.0.0.1', 3206)
电话来了
recv: b'dfdfdfdf'
client端:
>>:dfdfdfdf
recv: DFDFDFDF
>>:
实现SSH客户端和服务端
- 客户端代码
#Author:yyqian
import socket
'''
ssh的客户端
且考虑到一次数据1024可能没有全部传输到
所以将数据全部长度和每次实际传入长度进行对比
判断是否传输完成
并将每次传输的数据累计起来 最后进行打印
'''
client = socket.socket()
client.connect(('localhost',9999))
while True:
cmd = input(">>:").strip()
if len(cmd)==0: continue
client.send(cmd.encode("utf-8"))
cmd_res_size = client.recv(1024)
print("命令结果大小:",cmd_res_size)
received_size = 0
received_data = b''
while received_size < int(cmd_res_size.decode()):
data = client.recv(1024)
received_size += len(data)
received_data += data
else :
print(received_data.decode())
client.close()
- 服务端代码
#Author:yyqian
import socket,os,time
server = socket.socket()
server.bind(('localhost',9999))
server.listen()
while True:
conn ,addr = server.accept()
print("new conn:",addr)
while True:
print("等待新指令")
data = conn.recv(1024)
if not data:
print("客户端已经断开")
break
print("执行指令:",data)
#接受字符串 执行结果也是字符串
cmd_res = os.popen(data.decode("utf-8")).read() # 接受字符串,执行结果也是字符串
print("before send",len(cmd_res))
if len(cmd_res) == 0:
cmd_res = "cmd has no output..."
conn.send(str(len(cmd_res.encode("utf-8"))).encode("utf-8")) # 先发大小给客户端
time.sleep(5)
conn.send(cmd_res.encode("utf-8"))
print("send done")
server.close()
- 结果检验
客户端
>>:pwd
命令结果大小: b'20'
cmd has no output...
>>:ipconfig
命令结果大小: b'1390'
Windows IP 配置
PPP 适配器 duoduo:
连接特定的 DNS 后缀 . . . . . . . :
IPv6 地址 . . . . . . . . . . . . : 2001:250:1006:d