利用基本的Socket 通信,模仿远程cmd命令:

Server

import socket
sk = socket.socket()
sk.bind(('127.0.0.1',8090))
sk.listen() conn,addr = sk.accept()
while True:
cmd = input('cmd : ')
if cmd == 'q':
conn.send(cmd.encode('utf-8'))
break
conn.send(cmd.encode('utf-8'))
print('stdout : ',conn.recv(1024).decode('gbk'))
conn.close()
sk.close()

Client

import socket # 内置模块 和os模块的功能有相似之处 能执行操作系统的命令的功能
import subprocess
sk = socket.socket()
sk.connect(('127.0.0.1',8090))
while True:
cmd = sk.recv(1024).decode('utf-8')
if cmd == 'q': break
res = subprocess.Popen(cmd,shell=True, # 表示要执行的是一条系统命令
stdout=subprocess.PIPE, # 存储执行结果的正常信息
stderr=subprocess.PIPE) # 存储执行结果的错误信息
sk.send(res.stdout.read())
sk.send(res.stderr.read())
sk.close()

基本的UDP :

import socket
sk = socket.socket(type=socket.SOCK_DGRAM)
sk.bind(('127.0.0.1',8090))
msg,addr = sk.recvfrom(1024)
while True:
cmd = input('cmd : ')
if cmd == 'q':
sk.sendto(cmd.encode('utf-8'),addr)
break
sk.sendto(cmd.encode('utf-8'),addr)
print('stdout : ',sk.recvfrom(2048)[0].decode('gbk'))
print('stderr : ',sk.recvfrom(2048)[0].decode('gbk'))
sk.close()
import socket
import subprocess
sk = socket.socket(type=socket.SOCK_DGRAM)
sk.sendto(b'',('127.0.0.1',8090))
while True:
cmd = sk.recvfrom(1024)[0].decode('utf-8')
if cmd == 'q': break
res = subprocess.Popen(cmd,shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
sk.sendto(res.stdout.read()*100,('127.0.0.1',8090))
sk.sendto(res.stderr.read(),('127.0.0.1',8090))
sk.close()

粘包及简单解决方法:

使用struct模块来转换数据长度。

server:

import socket,struct,json
import subprocess
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加 phone.bind(('127.0.0.1',8080)) phone.listen(5) while True:
conn,addr=phone.accept()
while True:
cmd=conn.recv(1024)
if not cmd:break
print('cmd: %s' %cmd) res=subprocess.Popen(cmd.decode('utf-8'),
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
err=res.stderr.read()
print(err)
if err:
back_msg=err
else:
back_msg=res.stdout.read() headers={'data_size':len(back_msg)}
print(headers)
head_json=json.dumps(headers)
print(head_json)
head_json_bytes=bytes(head_json,encoding='utf-8')
print(head_json_bytes) head = struct.pack('i',len(head_json_bytes))
print(struct.unpack('i',head)[0])
conn.send(head) # 先发报头的长度
conn.send(head_json_bytes) # 再发报头
conn.sendall(back_msg) # 在发真实的内容 conn.close() # 服务端:定制稍微复杂一点的报头

client

from socket import *
import struct,json ip_port=('127.0.0.1',8080)
client=socket(AF_INET,SOCK_STREAM)
client.connect(ip_port) while True:
cmd=input('>>: ')
if not cmd:continue
client.send(bytes(cmd,encoding='utf-8')) head=client.recv(4)
head_json_len=struct.unpack('i',head)[0]
head_json=json.loads(client.recv(head_json_len).decode('utf-8'))
data_len=head_json['data_size'] recv_size=0
recv_data=b''
while recv_size < data_len:
recv_data+=client.recv(1024)
recv_size+=len(recv_data) print(recv_size) # print(recv_data.decode('utf-8'))
print(recv_data.decode('gbk')) #windows默认gbk编码 # 客户端

练习:up_down   server:

import json
import socket sk = socket.socket()
sk.bind(('127.0.0.1',8080))
sk.listen() conn,addr = sk.accept()
content = conn.recv(1024).decode('utf-8')
content_dic = json.loads(content)
if content_dic['operate'] == 'upload':
conn.send(b'received!')
with open(content_dic['filename'],'wb') as f:
while content_dic['filesize']:
file = conn.recv(1024)
f.write(file)
content_dic['filesize'] -= len(file)
conn.close()
sk.close()

client:

import os
import json
import socket sk = socket.socket()
sk.connect(('127.0.0.1',8080)) def get_filename(file_path):
filename = os.path.basename(file_path)
return filename #选择 操作
operate = ['upload','download']
for num,opt in enumerate(operate,1):
print(num,opt)
num = int(input('请输入您要做的操作序号 : '))
if num == 1:
'''上传操作'''
#file_path = 'E:\python10\day33\作业.py'
file_path = input('请输入要上传的文件路径 : ')
# 告诉对方要上传的文件的名字
file_name = get_filename(file_path)
# 读要上传的文件 存成字符串
with open(file_path,encoding='utf-8') as f:
content = f.read() dic = {'operate':'upload','filename':file_name,'content':content}
# 将字符串send给server端
str_dic = json.dumps(dic)
sk.send(str_dic.encode('utf-8'))
# server端接收 bytes转码程字符串
# server端打开文件 写文件
elif num == 2:
'''下载操作'''
pass sk.close()

详细教程参考:http://www.cnblogs.com/Eva-J/articles/8244551.html

subprocess 模块 示例:

import subprocess
import os # ret = os.popen() # 拿到的结果和错误会连在一起。 # 用法示例
res = subprocess.Popen('dir',
shell=True,
stdout=subprocess.PIPE, # 将stdout/stderr 都装入容器
stderr=subprocess.PIPE) print(res.stdout.read().decode('gbk')) # 可以分开取得结果 和 错误信息
print(res.stderr.read().decode('gbk'))

hmac  模块:

server  在服务端完成验证

import os
import socket
import hmac secret_key=b'egg'
sk = socket.socket()
sk.bind(('127.0.0.1',8080))
sk.listen() def check_conn(conn):
msg = os.urandom(32) # 长度32位的bytes
conn.send(msg)
h = hmac.new(secret_key,msg)
digest= h.digest() # 加salt后计算的hash结果
client_digest=conn.recv(1024)
print(client_digest)
return hmac.compare_digest(digest,client_digest) conn,addr = sk.accept()
res = check_conn(conn)
if res:
print('legal')
conn.close()
else:
print('illegal')
conn.close() sk.close()

client

import socket
import hmac secret_key=b'egg' sk = socket.socket()
sk.connect(('127.0.0.1',8080))
msg = sk.recv(1024)
h=hmac.new(secret_key,msg)
digest= h.digest()
sk.send(digest) sk.close()

利用hmac验证客户端的合法性:

import os
import socket
import hmac
def check_client(conn):
secret_key = b'egg' # 密钥
send_str = os.urandom(32)
conn.send(send_str)
hmac_obj = hmac.new(secret_key,send_str)
secret_ret = hmac_obj.digest() # bytes类型
if conn.recv(1024) == secret_ret:
print('合法的客户端')
return True
else:
print('非法的客户端')
return False sk = socket.socket()
sk.bind(('127.0.0.1',8090))
sk.listen() conn,addr = sk.accept()
ret = check_client(conn)
while ret:
inp = input('>>>')
conn.send(inp.encode('utf-8'))
msg = conn.recv(1024)
print(msg.decode('utf-8'))
conn.close()
sk.close()
import socket
import hmac
sk = socket.socket()
sk.connect(('127.0.0.1',8090)) recv = sk.recv(1024)
# 用和server端相同的手法对这个字符串进行摘要
secret_key = b'egg' # 密钥
hmac_obj = hmac.new(secret_key,recv)
ret = hmac_obj.digest()
sk.send(ret)
msg = sk.recv(1024)
if msg:
print(msg.decode('utf-8'))
while True:
inp = input('>>>')
sk.send(inp.encode('utf-8'))
msg = sk.recv(1024)
print(msg.decode('utf-8'))
sk.close()

socketserver 模块:

server

import socketserver

# 类名随意,但必须继承 BaseRequestHandler
class MyServer(socketserver.BaseRequestHandler):
def handle(self): # 固定的方法
self.request.send(b'hello') # conn
msg = self.request.recv(1024).decode('utf-8')
print(msg) server = socketserver.ThreadingTCPServer( # 多线程实现并发
('127.0.0.1',9000),
MyServer) # 传入写的类 server.serve_forever() # 永久服务

client

# tcp
# 粘包
# 在同一时间只能处理一个客户端的请求
import socket sk = socket.socket()
sk.connect(('127.0.0.1',9000))
print(sk.recv(1024)) msg = input('>>>').encode('utf-8')
sk.send(msg)
sk.close()

login server

import json
import hashlib
import socketserver def md5_pwd(user,pwd):
md5_obj = hashlib.md5(user.encode('utf-8'))
md5_obj.update(pwd.encode('utf-8'))
ret = md5_obj.hexdigest()
return ret def login(userinfo):
user_dic = json.loads(userinfo)
passwd = md5_pwd(user_dic['username'], user_dic['passwd'])
with open('userinfo') as f:
for line in f:
user, pwd = line.split('|')
if user_dic['username'] == user and passwd == pwd:
print('登录成功')
break class MyServer(socketserver.BaseRequestHandler):
def handle(self):
userinfo = self.request.recv(1024).decode('utf-8')
login(userinfo) server = socketserver.ThreadingTCPServer(
('127.0.0.1',9000),
MyServer) server.serve_forever()

login client

import json
import socket ADDR = ('127.0.0.1',9000) def get_socket():
sk = socket.socket()
sk.connect(ADDR)
return sk # 输入账号
username = input('username >>>')
passwd = input('password >>>')
if username.strip() and passwd.strip():
sk = get_socket()
dic = {'username':username,'passwd':passwd}
str_dic = json.dumps(dic)
sk.send(str_dic.encode('utf-8')) sk.close()

采用进程池方式 启用的多进程 socket server

import socket
from multiprocessing import Pool def func(conn):
conn.send(b'gooooood')
print(conn.recv(1024).decode('utf8'))
conn.close() if __name__ == '__main__':
p = Pool(5)
sk = socket.socket()
sk.bind(('127.0.0.1',8081))
sk.listen()
while 1:
conn,addr = sk.accept()
p.apply_async(func,args=(conn,)) # 异步方式
sk.close()
import socket

sk = socket.socket()
sk.connect(('127.0.0.1',8081))
ret = sk.recv(1024).decode('utf8')
print(ret) msg = input('>>>').encode('utf8')
sk.send(msg)
sk.close()
# 客户端用于测试

python网络基础_socket的更多相关文章

  1. Python服务器开发二:Python网络基础

    Python服务器开发二:Python网络基础   网络由下往上分为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层. HTTP是高层协议,而TCP/IP是个协议集,包过许多的子协议.包括: ...

  2. 27 python 网络基础之网络协议

    一.操作系统基础 操作系统:(Operating System,简称OS)是管理和控制计算机硬件与软件资源的计算机程序,是直接运行在“裸机”上的最基本的系统软件,任何其他软件都必须在操作系统的支持下才 ...

  3. python 网络基础 之 网络协议

    osi 七层协议 互联网协议按照功能不同分为osi七层或者tcp/ip 五层或tcp/ip 四层 tcp/ip 四层 1.应用层 2.传输层 3.网络层 4.网络接口层 tcp/ip 五层 1.应用层 ...

  4. Python(网络基础)

    day33 参考:http://www.cnblogs.com/linhaifeng/articles/5937962.html IP协议: 规定网络地址的协议叫ip协议,它定义的地址称之为ip地址, ...

  5. Python网络编程基础pdf

    Python网络编程基础(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1VGwGtMSZbE0bSZe-MBl6qA 提取码:mert 复制这段内容后打开百度网盘手 ...

  6. python网络编程基础(线程与进程、并行与并发、同步与异步、阻塞与非阻塞、CPU密集型与IO密集型)

    python网络编程基础(线程与进程.并行与并发.同步与异步.阻塞与非阻塞.CPU密集型与IO密集型) 目录 线程与进程 并行与并发 同步与异步 阻塞与非阻塞 CPU密集型与IO密集型 线程与进程 进 ...

  7. Python服务器开发 -- 网络基础-乾颐堂

    网络由下往上分为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层. HTTP是高层协议,而TCP/IP是个协议集,包过许多的子协议.包括:传输层的 FTP,UDP,TCP协议等,网络层的ip ...

  8. Python进程间通信和网络基础

    Python进程间通信和网络基础 Python支持多种进程间通讯的方式, 有单机通信的signal和mmap等, 也有可以通过网络的socket方式, 这里先介绍select等的有关知识, socke ...

  9. python基础(29):网络编程(软件开发架构、网络基础、套接字初使用)

    1. 软件开发架构 我们了解的程序之间通讯的应用可分为两种: 第一种是应用类:qq.微信.百度网盘.腾讯视频这一类是属于需要安装的桌面应用. 第二种是web类:比如百度.知乎.博客园等使用浏览器访问就 ...

随机推荐

  1. Autofac IOC框架

    ASP.NET Core自带了一个轻量级的IOC容器     但是只提供了最基本的AddXXX方法来绑定实例关系     需要一个一个添加   可以使用其他IOC容器来替换内置的 ABP自带Castl ...

  2. .net扩展方法

    http://www.cnblogs.com/landeanfen/p/4632467.html 看了博客才知道定义一个Util工具类并且在工具类里面写静态扩展方法并不是最好的选择.

  3. js 上下滚动加停顿效果,js 跑马灯加停顿效果

    <div id="middle"> <ul id="slide1"> <li>尾号1183的用户刚刚领取了 78.23元 的 ...

  4. Django 管理站点

    这一部分是关于 Django 的自动管理界面.这个特性是这样起作用的:它读取你模式中的元数据,然后提供给你一个强大而且可以使用的界面,网站管理者可以用它立即工作.在这里我们将讨论如何激活,使用和定制这 ...

  5. 用Python实现支持向量机并处理Iris数据集

    SVM全称是Support Vector Machine,即支持向量机,是一种监督式学习算法.它主要应用于分类问题,通过改进代码也可以用作回归.所谓支持向量就是距离分隔面最近的向量.支持向量机就是要确 ...

  6. centos7安装python,mariaDB,django,nginx

    0,安装centos7 centos默认不开启网卡,需要在安装时将ens33设置为on,或者后续通过vi ifcfg-ens33,找到onboot,设置为yes ssg登陆centos7时,如果提示W ...

  7. C++之标准库map

    目录 1.成员函数 2.元素访问 3.迭代器Iterators(C++ 11) 4.容量Capacity 5.修改函数(C++ 11和C++ 17) 6.查找表Lookup 7.观察Observers ...

  8. C# 抽象类和接口的差别

    抽象类和接口最终目的:抽象类实现多态化,接口实现功能化.比如汽车:接口就是轮子,发动机,车身等零部件,抽象类则是颜色,款式,型号等参数性东西. 抽象类(abstract): (1) 抽象方法只作声明, ...

  9. java的equals()与hashCode()以及包装类中的实现

    1. hashcode 1.1 hashcode来源 1.2 hashcode的形式 1.3 hashcode目的 1.4 hashcode规则 1.5 hashcode作用体现 1.6 重写hash ...

  10. 将对象转成 json 以及 将字符串 hash(SHA1) 加密

    如下: /// <summary> /// 生成 Json /// </summary> /// <param name="obj"></ ...