socket编程
socket编程,是一切web服务的祖宗,没有socket,就没有其他web服务,因为一切web服务都是在socket基础上进行加工处理。
那么下面直接上示例:
server端的代码
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket,os
sk = socket.socket()
sk.bind(('localhost',6969))
sk.listen(5)#这里的数字5表示最后可监听的客户端连接数,参数要写,不写可能会出错,而且数字不要太大
while True:
print('等客户端连接。。。。')
conn,addr = sk.accept()
print('客户端连接进来了,准备收发数据了。。。')
while True:
data = conn.recv(1024)
if not data:
print('client has losted......')
break
#这里要用sendall来代替send,因为sendall会尝试发送所有数据,其实它内部是通过递归调用send
#将所有内容发送出去。不过不是一次性发送,而是每次按照一定的大小发送。
res = os.popen(data).read()
conn.sendall(res)
sk.close()
client端的代码:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
sk = socket.socket()
sk.connect(('localhost',6969))
while True:
user_input = raw_input('input>>>:').strip()
if len(user_input) == 0:continue
sk.sendall(user_input.encode(encoding='utf-8'))
#这里的recv中的数值可以更改,但是接受的数据并不是以数值大小的绝对来接受,
#当数值输入的很大,但接受数据还会按照一定的大小来接受。
data = sk.recv(1024)
print(data.decode())
sk.close()
socket ssh实例:
1、服务端
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()).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())).encode("utf-8") ) #先发大小给客户端
conn.recv(1024) #这命令主要为了防止粘包
conn.send(cmd_res.encode("utf-8"))
print("send done")
server.close()
2、客户端:
import socket
client = socket.socket()
#client.connect(('192.168.16.200',9999))
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)
client.send('准备接受数据'.encode('utf-8')) #这命令主要为了防止粘包
received_size = 0
received_data = b''
while received_size < int(cmd_res_size.decode()) :
data = client.recv(1024)
received_size += len(data) #每次收到的有可能小于1024,所以必须用len判断
#print(data.decode())
received_data += data
else:
print("cmd res receive done...",received_size)
print(received_data.decode())
client.close()
socket FTP实例:
1、服务端:
import hashlib
import socket ,os,time
server = socket.socket()
server.bind(('0.0.0.0',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
cmd,filename = data.decode().split()
print(filename)
if os.path.isfile(filename):
f = open(filename,"rb")
m = hashlib.md5()
file_size = os.stat(filename).st_size
conn.send( str(file_size).encode() ) #send file size
conn.recv(1024) #wait for ack
for line in f:
m.update(line)
conn.send(line)
print("file md5", m.hexdigest())
f.close()
conn.send(m.hexdigest().encode()) #send md5
print("send done")
server.close()
2、客户端:
import socket
import hashlib
client = socket.socket()
client.connect(('localhost', 9999))
while True:
cmd = input(">>:").strip()
if len(cmd) == 0: continue
if cmd.startswith("get"):
client.send(cmd.encode())
server_response = client.recv(1024)
print("servr response:", server_response)
client.send(b"ready to recv file")
file_total_size = int(server_response.decode())
received_size = 0
filename = cmd.split()[1]
f = open(filename + ".new", "wb")
m = hashlib.md5()
while received_size < file_total_size:
if file_total_size - received_size > 1024: # 要收不止一次
size = 1024
else: # 最后一次了,剩多少收多少
size = file_total_size - received_size
print("last receive:", size)
data = client.recv(size)
received_size += len(data)
m.update(data)
f.write(data)
# print(file_total_size,received_size)
else:
new_file_md5 = m.hexdigest()
print("file recv done", received_size, file_total_size)
f.close()
server_file_md5 = client.recv(1024)
print("server file md5:", server_file_md5)
print("client file md5:", new_file_md5)
client.close()
浙公网安备 33010602011771号