明天游人如织高级高校都以运用drcom顾客端管住学生的上网流量等音讯,在Linux下Drcom客户端版本有的院校恐怕未有揭露,大家能够动用Python模拟登入Drcom。
下边正是爬虫的兼具代码,完全,透彻的当众,你会不会写程序都能够行使,不过请先装个linux系统,具有公网条件,然后运维:
黏包的消除方案
set
无序,不重复,可嵌套。
最重大的正是验证的服务器地址,这么些要求抓包分析出ip,自行Google,很轻便能够兑现的
python startCrawler.py
有不可或缺提醒你,数据库字段代码中都有,请您自个儿建张表格,这几个太简单了,就十分的少说了。同偶尔候作者也提供一下下载地址,源码都在:
下载地址1 下载地址2
杀鸡取蛋方案一
题指标根源在于,接收端不明白发送端就要传送的字节流的长短,所以化解粘包的不二秘技正是环绕,如何让发送端在发送数据前,把自个儿快要发送的字节流总大小让接收端知晓,然后接收端来二个死循环接收完全数数据。
#_*_coding:utf-8_*_
import socket,subprocess
ip_port=(‘127.0.0.1’,8080)
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(ip_port)
s.listen(5)
while True:
conn,addr=s.accept()
print(‘客户端’,addr)
while True:
msg=conn.recv(1024)
if not msg:break
res=subprocess.Popen(msg.decode(‘utf-8’),shell=True,\
stdin=subprocess.PIPE,\
stderr=subprocess.PIPE,\
stdout=subprocess.PIPE)
err=res.stderr.read()
if err:
ret=err
else:
ret=res.stdout.read()
data_length=len(ret)
conn.send(str(data_length).encode(‘utf-8’))
data=conn.recv(1024).decode(‘utf-8’)
if data == ‘recv_ready’:
conn.sendall(ret)
conn.close()
服务端
#_*_coding:utf-8_*_
import socket,subprocess
ip_port=('127.0.0.1',8080)
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(ip_port)
s.listen(5)
while True:
conn,addr=s.accept()
print('客户端',addr)
while True:
msg=conn.recv(1024)
if not msg:break
res=subprocess.Popen(msg.decode('utf-8'),shell=True,\
stdin=subprocess.PIPE,\
stderr=subprocess.PIPE,\
stdout=subprocess.PIPE)
err=res.stderr.read()
if err:
ret=err
else:
ret=res.stdout.read()
data_length=len(ret)
conn.send(str(data_length).encode('utf-8'))
data=conn.recv(1024).decode('utf-8')
if data == 'recv_ready':
conn.sendall(ret)
conn.close()
#_*_coding:utf-8_*_
import socket,time
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
res=s.connect_ex((‘127.0.0.1’,8080))
while True:
msg=input(‘>>: ‘).strip()
if len(msg) == 0:continue
if msg == ‘quit’:break
s.send(msg.encode(‘utf-8’))
length=int(s.recv(1024).decode(‘utf-8’))
s.send(‘recv_ready’.encode(‘utf-8’))
send_size=0
recv_size=0
data=b”
while recv_size < length:
data+=s.recv(1024)
recv_size+=len(data)
print(data.decode(‘utf-8’))
客户端
#_*_coding:utf-8_*_
import socket,time
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
res=s.connect_ex(('127.0.0.1',8080))
while True:
msg=input('>>: ').strip()
if len(msg) == 0:continue
if msg == 'quit':break
s.send(msg.encode('utf-8'))
length=int(s.recv(1024).decode('utf-8'))
s.send('recv_ready'.encode('utf-8'))
send_size=0
recv_size=0
data=b''
while recv_size < length:
data+=s.recv(1024)
recv_size+=len(data)
print(data.decode('utf-8'))
存在的问题:
程序的运行速度远快于网络传输速度,所以在发送一段字节前,先用send去发送该字节流长度,这种方式会放大网络延迟带来的性能损耗
函数
成立函数:
1、def关键字,创制函数
2、函数名
3、()
4、函数体
5、返回值
#!/usr/bin/env python
# encoding: utf-8
赶尽杀绝方案进级
刚巧的方法,难点在于大家大家在殡葬
大家得以信赖二个模块,那么些模块能够把要发送的数额长度转变到固定长度的字节。那样顾客端每一回接到信息从前如若先接受那一个一定长度字节的剧情看一看接下去要收下的消息大小,那么最后接受的数量假若达到这几个值就甘休,就能够刚好相当少不菲的接受完整的数码了。
发邮件函数
-
def sendmail():
-
import smtplib
-
from email.mime.text import
MIMEText -
from email.utils import formataddr
-
#四个参数:第贰个为文本内容,第三个plain 设置文本格式,第多个 utf-8 设置编码
-
msg =
MIMEText(‘邮件内容’,’plain’,’utf-8′) -
msg[‘From’] = formataddr([“发件人名称”,’发件人邮箱’])
-
msg[‘To’] = formataddr([“哈哈”,’收件人邮箱’])
-
msg[‘Subject’] = “邮件主旨”
-
-
server = smtplib.SMTP(“smtp地址”,端口)
-
#需求在开启SMTP,否则发送战败
-
server.login(“发件人邮箱”,”密码”)
-
server.sendmail(‘发件人邮箱’,[‘收件人邮箱’],msg.as_string())
-
server.quit()
-
sendmail()
Linux下运作py脚本 (必得设置Python2)
“””
author:haoning
create time:2015.8.1
“””
struct模块
该模块能够把四个连串,如数字,转成固定长度的bytes
>>> struct.pack('i',1111111111111)
struct.error: 'i' format requires -2147483648 <= number <= 2147483647 #这个是范围
import json,struct
#假设通过客户端上传1T:1073741824000的文件a.txt
#为避免粘包,必须自定制报头
header={'file_size':1073741824000,'file_name':'/a/b/c/d/e/a.txt','md5':'8f6fbf8347faa4924a76856701edb0f3'} #1T数据,文件路径和md5值
#为了该报头能传送,需要序列化并且转为bytes
head_bytes=bytes(json.dumps(header),encoding='utf-8') #序列化并转成bytes,用于传输
#为了让客户端知道报头的长度,用struck将报头长度这个数字转成固定长度:4个字节
head_len_bytes=struct.pack('i',len(head_bytes)) #这4个字节里只包含了一个数字,该数字是报头的长度
#客户端开始发送
conn.send(head_len_bytes) #先发报头的长度,4个bytes
conn.send(head_bytes) #再发报头的字节格式
conn.sendall(文件内容) #然后发真实内容的字节格式
#服务端开始接收
head_len_bytes=s.recv(4) #先收报头4个bytes,得到报头长度的字节格式
x=struct.unpack('i',head_len_bytes)[0] #提取报头的长度
head_bytes=s.recv(x) #按照报头长度x,收取报头的bytes格式
header=json.loads(json.dumps(header)) #提取报头
#最后根据报头的内容提取真实的数据,比如
real_data_len=s.recv(header['file_size'])
s.recv(real_data_len)
#_*_coding:utf-8_*_
#
__author__ = ‘Linhaifeng’
import struct
import binascii
import ctypes
values1 = (1, ‘abc’.encode(‘utf-8’), 2.7)
values2 = (‘defg’.encode(‘utf-8’),101)
s1 = struct.Struct(‘I3sf’)
s2 = struct.Struct(‘4sI’)
print(s1.size,s2.size)
prebuffer=ctypes.create_string_buffer(s1.size+s2.size)
print(‘Before : ‘,binascii.hexlify(prebuffer))
# t=binascii.hexlify(‘asdfaf’.encode(‘utf-8’))
# print(t)
s1.pack_into(prebuffer,0,*values1)
s2.pack_into(prebuffer,s1.size,*values2)
print(‘After pack’,binascii.hexlify(prebuffer))
print(s1.unpack_from(prebuffer,0))
print(s2.unpack_from(prebuffer,s1.size))
s3=struct.Struct(‘ii’)
s3.pack_into(prebuffer,0,123,123)
print(‘After pack’,binascii.hexlify(prebuffer))
print(s3.unpack_from(prebuffer,0))
至于struct的事无巨细用法
#_*_coding:utf-8_*_
#http://www.cnblogs.com/coser/archive/2011/12/17/2291160.html
__author__ = 'Linhaifeng'
import struct
import binascii
import ctypes
values1 = (1, 'abc'.encode('utf-8'), 2.7)
values2 = ('defg'.encode('utf-8'),101)
s1 = struct.Struct('I3sf')
s2 = struct.Struct('4sI')
print(s1.size,s2.size)
prebuffer=ctypes.create_string_buffer(s1.size+s2.size)
print('Before : ',binascii.hexlify(prebuffer))
# t=binascii.hexlify('asdfaf'.encode('utf-8'))
# print(t)
s1.pack_into(prebuffer,0,*values1)
s2.pack_into(prebuffer,s1.size,*values2)
print('After pack',binascii.hexlify(prebuffer))
print(s1.unpack_from(prebuffer,0))
print(s2.unpack_from(prebuffer,s1.size))
s3=struct.Struct('ii')
s3.pack_into(prebuffer,0,123,123)
print('After pack',binascii.hexlify(prebuffer))
print(s3.unpack_from(prebuffer,0))
函数中的return
-
def f1():
-
print(123)
-
#在函数中,一旦实践return,函数实践进度马上停下
-
return “111”
-
print(456)
-
-
r = f1()
-
print(r)
命令行: python drclient.py
import hashlib
import os
import time
import datetime
import traceback
import sys
import random
import json
import socket
import threading
from hashlib import sha1 #进行hash加密
from random import randint
from struct import unpack
from socket import inet_ntoa
from threading import Timer, Thread
from time import sleep
from collections import deque
from Queue import Queue
import MySQLdb as mdb #数据库连接器
import metautils
import downloadTorrent
from bencode import bencode, bdecode
import pygeoip
DB_HOST = ‘127.0.0.1’
DB_USER = ‘root’
DB_PASS = ‘root’
BOOTSTRAP_NODES = (
(“67.215.246.10”, 6881),
(“82.221.103.244”, 6881),
(“23.21.224.150”, 6881)
)
RATE = 1 #调整速率
TID_LENGTH = 2
RE_JOIN_DHT_INTERVAL = 3
TOKEN_LENGTH = 2
INFO_HASH_LEN = 500000 #50w数据非常的小,限制内部存款和储蓄器不至于消耗太大
CACHE_LEN = 100 #革新数据库缓存
WAIT_DOWNLOAD = 80
geoip = pygeoip.GeoIP(‘GeoIP.dat’)
def is_ip_allowed(ip):
country = geoip.country_code_by_addr(ip)
if country in (‘CN’,’TW’,’JP’,’HK’, ‘KR’):
return True
return False
def entropy(length):
return “”.join(chr(randint(0, 255)) for _ in xrange(length))
def random_id():
h = sha1()
h.update(entropy(20))
return h.digest()
def decode_nodes(nodes):
n = []
length = len(nodes)
if (length % 26) != 0:
return n
for i in range(0, length, 26):
nid = nodes[i:i+20]
ip = inet_ntoa(nodes[i+20:i+24])
port = unpack(“!H”, nodes[i+24:i+26])[0]
n.append((nid, ip, port))
return n
def timer(t, f):
Timer(t, f).start()
def get_neighbor(target, nid, end=10):
return target[:end]+nid[end:]
class KNode(object):
def __init__(self, nid, ip, port):
self.nid = nid
self.ip = ip
self.port = port
class DHTClient(Thread):
def __init__(self, max_node_qsize):
Thread.__init__(self)
self.setDaemon(True)
self.max_node_qsize = max_node_qsize
self.nid = random_id()
self.nodes = deque(maxlen=max_node_qsize)
def send_krpc(self, msg, address):
try:
self.ufd.sendto(bencode(msg), address)
except Exception:
pass
def send_find_node(self, address, nid=None):
nid = get_neighbor(nid, self.nid) if nid else self.nid
tid = entropy(TID_LENGTH)
msg = {
“t”: tid,
“y”: “q”,
“q”: “find_node”,
“a”: {
“id”: nid,
“target”: random_id()
}
}
self.send_krpc(msg, address)
def join_DHT(self):
for address in BOOTSTRAP_NODES:
self.send_find_node(address)
def re_join_DHT(self):
if len(self.nodes) == 0:
self.join_DHT()
timer(RE_JOIN_DHT_INTERVAL, self.re_join_DHT)
def auto_send_find_node(self):
wait = 1.0 / self.max_node_qsize
while True:
try:
node = self.nodes.popleft()
self.send_find_node((node.ip, node.port), node.nid)
except IndexError:
pass
try:
sleep(wait)
except KeyboardInterrupt:
os._exit(0)
def process_find_node_response(self, msg, address):
nodes = decode_nodes(msg[“r”][“nodes”])
for node in nodes:
(nid, ip, port) = node
if len(nid) != 20: continue
if ip == self.bind_ip: continue
n = KNode(nid, ip, port)
self.nodes.append(n)
class DHTServer(DHTClient): #获得info_hash
def __init__(self, master, bind_ip, bind_port,
max_node_qsize):
DHTClient.__init__(self, max_node_qsize)
self.master = master
self.bind_ip = bind_ip
self.bind_port = bind_port
self.speed=0
self.process_request_actions
= {
“get_peers”: self.on_get_peers_request,
“announce_peer”: self.on_announce_peer_request,
}
self.ufd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM,
socket.IPPROTO_UDP)
self.ufd.bind((self.bind_ip, self.bind_port))
timer(RE_JOIN_DHT_INTERVAL, self.re_join_DHT)
def run(self):
self.re_join_DHT()
while True:
try:
(data, address) = self.ufd.recvfrom(65536)
msg = bdecode(data)
self.on_message(msg, address)
except Exception:
pass
def on_message(self, msg, address):
global RATE #设为全局量
try:
if msg[“y”] == “r”:
if msg[“r”].has_key(“nodes”):
self.process_find_node_response(msg, address)
#意识节点
elif msg[“y”] == “q”:
try:
self.speed+=1
if self.speed % 10000 ==0:
RATE=random.randint(1,3)
if RATE==2:
RATE=1
if RATE==3:
RATE=10
if self.speed>100000:
self.speed=0
if self.speed % RATE==0:
#数码过多,占用cpu太多,划分限制速度,1,1,10
self.process_request_actions[msg[“q”]](msg, address)
#拍卖任何节点的呼吁,这么些进度获得info_hash
#self.process_request_actions[msg[“q”]](msg,
address) #拍卖其他节点的央浼,这么些进度获得info_hash
except KeyError:
self.play_dead(msg, address)
except KeyError:
pass
def on_get_peers_request(self, msg, address):
try:
infohash = msg[“a”][“info_hash”]
tid = msg[“t”]
nid = msg[“a”][“id”]
token = infohash[:TOKEN_LENGTH]
msg = {
“t”: tid,
“y”: “r”,
“r”: {
“id”: get_neighbor(infohash, self.nid),
“nodes”: “”,
“token”: token
}
}
self.master.log(infohash, address)
self.send_krpc(msg, address)
except KeyError:
pass
def on_announce_peer_request(self, msg, address):
try:
infohash = msg[“a”][“info_hash”]
token = msg[“a”][“token”]
nid = msg[“a”][“id”]
tid = msg[“t”]
if infohash[:TOKEN_LENGTH] == token:
if msg[“a”].has_key(“implied_port “) and
msg[“a”][“implied_port “] != 0:
port = address[1]
else:
port = msg[“a”][“port”]
self.master.log_announce(infohash, (address[0],
port))
except Exception:
print ‘error’
pass
finally:
self.ok(msg, address)
def play_dead(self, msg, address):
try:
tid = msg[“t”]
msg = {
“t”: tid,
“y”: “e”,
“e”: [202, “Server Error”]
}
self.send_krpc(msg, address)
except KeyError:
pass
def ok(self, msg, address):
try:
tid = msg[“t”]
nid = msg[“a”][“id”]
msg = {
“t”: tid,
“y”: “r”,
“r”: {
“id”: get_neighbor(nid, self.nid)
}
}
self.send_krpc(msg, address)
except KeyError:
pass
class Master(Thread): #解析info_hash
def __init__(self):
Thread.__init__(self)
self.setDaemon(True)
self.queue = Queue()
self.cache = Queue()
self.count=0
self.mutex = threading.RLock()
#可重入锁,使单线程可以另行赢得已经得到的?
self.waitDownload = Queue()
self.metadata_queue = Queue()
self.dbconn = mdb.connect(DB_HOST, DB_USER, DB_PASS,
‘oksousou’, charset=’utf8′)
self.dbconn.autocommit(False)
self.dbcurr = self.dbconn.cursor()
self.dbcurr.execute(‘SET NAMES utf8’)
self.visited = set()
def lock(self): #加锁
self.mutex.acquire()
def unlock(self): #解锁
self.mutex.release()
def work(self,item):
黏包的化解措施,python爬虫dht磁力源代码开源。 print “start thread”,item
while True:
self.prepare_download_metadata()
self.lock()
self.download_metadata()
self.unlock()
self.lock()
self.got_torrent()
self.unlock()
def start_work(self,max):
for item in xrange(max):
t = threading.Thread(target=self.work, args=(item,))
t.setDaemon(True)
t.start()
#入队的种子成效越来越高
def log_announce(self, binhash, address=None):
if self.queue.qsize() < INFO_HASH_LEN :
#大于INFO_HASH_LEN就不要入队,不然前边来比不上处理
if is_ip_allowed(address[0]):
self.queue.put([address, binhash]) #获得info_hash
def log(self, infohash, address=None):
if self.queue.qsize() < INFO_HASH_LEN:
#大于INFO_HASH_LEN/2就毫无入队,不然前面来不比管理
if is_ip_allowed(address[0]):
self.queue.put([address, infohash])
def prepare_download_metadata(self):
if self.queue.qsize() == 0:
sleep(2)
#从queue中获得info_hash用来下载
address, binhash= self.queue.get()
if binhash in self.visited:
return
if len(self.visited) > 100000:
#高于一千00重新载入参数队列,以为已经访谈过了
self.visited = set()
self.visited.add(binhash)
#跟新已经访问过的info_hash
info_hash = binhash.encode(‘hex’)
utcnow = datetime.datetime.utcnow()
self.cache.put((address,binhash,utcnow)) #装入缓存队列
def download_metadata(self):
if self.cache.qsize() > CACHE_LEN/2: #出队创新下载
while self.cache.qsize() > 0: #排空队列
address,binhash,utcnow = self.cache.get()
美高梅开户网址, info_hash = binhash.encode(‘hex’)
self.dbcurr.execute(‘SELECT id FROM search_hash WHERE
info_hash=%s’, (info_hash,))
y = self.dbcurr.fetchone()
if y:
# 更新近来意识时间,乞求数
self.dbcurr.execute(‘UPDATE search_hash SET
last_seen=%s, requests=requests+1 WHERE info_hash=%s’, (utcnow,
info_hash))
else:
self.waitDownload.put((address, binhash))
self.dbconn.commit()
if self.waitDownload.qsize() > WAIT_DOWNLOAD:
while self.waitDownload.qsize() > 0:
address,binhash = self.waitDownload.get()
t =
threading.Thread(target=downloadTorrent.download_metadata,
args=(address, binhash, self.metadata_queue))
t.setDaemon(True)
t.start()
def decode(self, s):
if type(s) is list:
s = ‘;’.join(s)
u = s
for x in (self.encoding, ‘utf8’, ‘gbk’, ‘big5’):
try:
u = s.decode(x)
return u
except:
pass
return s.decode(self.encoding, ‘ignore’)
def decode_utf8(self, d, i):
if i+’.utf-8′ in d:
return d[i+’.utf-8′].decode(‘utf8’)
return self.decode(d[i])
def parse_metadata(self, data): #剖判种子
info = {}
self.encoding = ‘utf8’
try:
torrent = bdecode(data) #编码后深入分析
if not torrent.get(‘name’):
return None
except:
return None
detail = torrent
info[‘name’] = self.decode_utf8(detail, ‘name’)
if ‘files’ in detail:
info[‘files’] = []
for x in detail[‘files’]:
if ‘path.utf-8’ in x:
v = {‘path’:
self.decode(‘/’.join(x[‘path.utf-8’])), ‘length’: x[‘length’]}
else:
v = {‘path’: self.decode(‘/’.join(x[‘path’])),
‘length’: x[‘length’]}
if ‘filehash’ in x:
v[‘filehash’] = x[‘filehash’].encode(‘hex’)
info[‘files’].append(v)
info[‘length’] = sum([x[‘length’] for x in
info[‘files’]])
else:
info[‘length’] = detail[‘length’]
info[‘data_hash’] =
hashlib.md5(detail[‘pieces’]).hexdigest()
return info
def got_torrent(self):
if self.metadata_queue.qsize() == 0:
return
binhash, address, data,start_time =
self.metadata_queue.get()
if not data:
return
try:
info = self.parse_metadata(data)
if not info:
return
except:
traceback.print_exc()
return
temp = time.time()
x = time.localtime(float(temp))
utcnow = time.strftime(“%Y-%m-%d %H:%M:%S”,x) # get time now
info_hash = binhash.encode(‘hex’) #磁力
info[‘info_hash’] = info_hash
# need to build tags
info[‘tagged’] = False
info[‘classified’] = False
info[‘requests’] = 1
info[‘last_seen’] = utcnow
info[‘create_time’] = utcnow
info[‘source_ip’] = address[0]
if info.get(‘files’):
files = [z for z in info[‘files’] if not
z[‘path’].startswith(‘_’)]
if not files:
files = info[‘files’]
else:
files = [{‘path’: info[‘name’], ‘length’:
info[‘length’]}]
files.sort(key=lambda z:z[‘length’], reverse=True)
bigfname = files[0][‘path’]
info[‘extension’] =
metautils.get_extension(bigfname).lower()
info[‘category’] =
metautils.get_category(info[‘extension’])
try:
try:
print ‘\n’, ‘Saved’, info[‘info_hash’],
info[‘name’], (time.time()-start_time), ‘s’, address[0]
except:
print ‘\n’, ‘Saved’, info[‘info_hash’]
ret = self.dbcurr.execute(‘INSERT INTO
search_hash(info_hash,category,data_hash,name,extension,classified,source_ip,tagged,’
运用struct化解黏包
借助struct模块,我们驾驭长度数字可以被转变到贰个正式尺寸的4字节数字。由此能够利用那个特点来预首发送数据长度。
发送时 | 接收时 |
先发送struct转换好的数据长度4字节 | 先接受4个字节使用struct转换成数字来获取要接收的数据长度 |
再发送数据 | 再按照长度接收数据 |
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()
conn.send(struct.pack(‘i’,len(back_msg))) #先发back_msg的长度
conn.sendall(back_msg) #在发真实的内容
conn.close()
服务端(自定制报头)
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()
conn.send(struct.pack('i',len(back_msg))) #先发back_msg的长度
conn.sendall(back_msg) #在发真实的内容
conn.close()
#_*_coding:utf-8_*_
import socket,time,struct
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
res=s.connect_ex((‘127.0.0.1’,8080))
while True:
msg=input(‘>>: ‘).strip()
if len(msg) == 0:continue
if msg == ‘quit’:break
s.send(msg.encode(‘utf-8’))
l=s.recv(4)
x=struct.unpack(‘i’,l)[0]
print(type(x),x)
# print(struct.unpack(‘I’,l))
r_s=0
data=b”
while r_s < x:
r_d=s.recv(1024)
data+=r_d
r_s+=len(r_d)
# print(data.decode(‘utf-8’))
print(data.decode(‘gbk’)) #windows默认gbk编码
客商端(自定制报头)
#_*_coding:utf-8_*_
import socket,time,struct
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
res=s.connect_ex(('127.0.0.1',8080))
while True:
msg=input('>>: ').strip()
if len(msg) == 0:continue
if msg == 'quit':break
s.send(msg.encode('utf-8'))
l=s.recv(4)
x=struct.unpack('i',l)[0]
print(type(x),x)
# print(struct.unpack('I',l))
r_s=0
data=b''
while r_s < x:
r_d=s.recv(1024)
data+=r_d
r_s+=len(r_d)
# print(data.decode('utf-8'))
print(data.decode('gbk')) #windows默认gbk编码
我们还足以把报头做成字典,字典里满含就要发送的切实地工作数据的详细音讯,然后json体系化,然后用struck将系列化后的数目长度打包成4个字节(4个和谐丰盛用了)
发送时 | 接收时 |
先发报头长度 |
先收报头长度,用struct取出来 |
再编码报头内容然后发送 | 根据取出的长度收取报头内容,然后解码,反序列化 |
最后发真实内容 | 从反序列化的结果中取出待取数据的详细信息,然后去取真实的数据内容 |
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)}
head_json=json.dumps(headers)
head_json_bytes=bytes(head_json,encoding=’utf-8′)
conn.send(struct.pack(‘i’,len(head_json_bytes))) #头阵报头的长短
conn.send(head_json_bytes) #再发报头
conn.sendall(back_msg) #在发真实的内容
conn.close()
服务端:定制稍微复杂一点的报头
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)}
head_json=json.dumps(headers)
head_json_bytes=bytes(head_json,encoding='utf-8')
conn.send(struct.pack('i',len(head_json_bytes))) #先发报头的长度
conn.send(head_json_bytes) #再发报头
conn.sendall(back_msg) #在发真实的内容
conn.close()
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_data.decode(‘utf-8’))
#print(recv_data.decode(‘gbk’)) #windows默认gbk编码
客户端
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_data.decode('utf-8'))
#print(recv_data.decode('gbk')) #windows默认gbk编码
函数的暗许重返值None
-
def f2():
-
print(123)
-
-
r = f2()
-
print(r)
- ‘length,create_time,last_seen,requests)
VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)’,
(info[‘info_hash’], info[‘category’],
info[‘data_hash’], info[‘name’], info[‘extension’],
info[‘classified’],
info[‘source_ip’], info[‘tagged’],
info[‘length’], info[‘create_time’], info[‘last_seen’],
info[‘requests’]))
if self.count %50 ==0:
self.dbconn.commit()
if self.count>100000:
self.count=0
except:
print self.name, ‘save error’, self.name, info
traceback.print_exc()
return
if __name__ == “__main__”:
#起步顾客端
master = Master()
master.start_work(150)
#起头服务器
dht = DHTServer(master, “0.0.0.0”, 6881, max_node_qsize=200)
dht.start()
dht.auto_send_find_node()
在乎,下边的代码有一段代码须求下载种子,所以下边的这段代码十一分根本:
FTP作业:上传下载文件
import socket
import struct
import json
import subprocess
import os
class MYTCPServer:
address_family = socket.AF_INET
socket_type = socket.SOCK_STREAM
allow_reuse_address = False
max_packet_size = 8192
coding=’utf-8′
request_queue_size = 5
server_dir=’file_upload’
def __init__(self, server_address, bind_and_activate=True):
“””Constructor. May be extended, do not override.”””
self.server_address=server_address
self.socket = socket.socket(self.address_family,
self.socket_type)
if bind_and_activate:
try:
self.server_bind()
self.server_activate()
except:
self.server_close()
raise
def server_bind(self):
“””Called by constructor to bind the socket.
“””
if self.allow_reuse_address:
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.socket.bind(self.server_address)
self.server_address = self.socket.getsockname()
def server_activate(self):
“””Called by constructor to activate the server.
“””
self.socket.listen(self.request_queue_size)
def server_close(self):
“””Called to clean-up the server.
“””
self.socket.close()
def get_request(self):
“””Get the request and client address from the socket.
“””
return self.socket.accept()
def close_request(self, request):
“””Called to clean up an individual request.”””
request.close()
def run(self):
while True:
self.conn,self.client_addr=self.get_request()
print(‘from client ‘,self.client_addr)
while True:
try:
head_struct = self.conn.recv(4)
if not head_struct:break
head_len = struct.unpack(‘i’, head_struct)[0]
head_json = self.conn.recv(head_len).decode(self.coding)
head_dic = json.loads(head_json)
print(head_dic)
#head_dic={‘cmd’:’put’,’filename’:’a.txt’,’filesize’:123123}
cmd=head_dic[‘cmd’]
if hasattr(self,cmd):
func=getattr(self,cmd)
func(head_dic)
except Exception:
break
def put(self,args):
file_path=os.path.normpath(os.path.join(
self.server_dir,
args[‘filename’]
))
filesize=args[‘filesize’]
recv_size=0
print(‘—–>’,file_path)
with open(file_path,’wb’) as f:
while recv_size < filesize:
recv_data=self.conn.recv(self.max_packet_size)
f.write(recv_data)
recv_size+=len(recv_data)
print(‘recvsize:%s filesize:%s’ %(recv_size,filesize))
tcpserver1=MYTCPServer((‘127.0.0.1’,8080))
tcpserver1.run()
#下列代码与主旨无关
class MYUDPServer:
“””UDP server class.”””
address_family = socket.AF_INET
socket_type = socket.SOCK_DGRAM
allow_reuse_address = False
max_packet_size = 8192
coding=’utf-8′
def get_request(self):
data, client_addr = self.socket.recvfrom(self.max_packet_size)
return (data, self.socket), client_addr
def server_activate(self):
# No need to call listen() for UDP.
pass
def shutdown_request(self, request):
# No need to shutdown anything.
self.close_request(request)
def close_request(self, request):
# No need to close anything.
pass
服务端
import socket
import struct
import json
import subprocess
import os
class MYTCPServer:
address_family = socket.AF_INET
socket_type = socket.SOCK_STREAM
allow_reuse_address = False
max_packet_size = 8192
coding='utf-8'
request_queue_size = 5
server_dir='file_upload'
def __init__(self, server_address, bind_and_activate=True):
"""Constructor. May be extended, do not override."""
self.server_address=server_address
self.socket = socket.socket(self.address_family,
self.socket_type)
if bind_and_activate:
try:
self.server_bind()
self.server_activate()
except:
self.server_close()
raise
def server_bind(self):
"""Called by constructor to bind the socket.
"""
if self.allow_reuse_address:
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.socket.bind(self.server_address)
self.server_address = self.socket.getsockname()
def server_activate(self):
"""Called by constructor to activate the server.
"""
self.socket.listen(self.request_queue_size)
def server_close(self):
"""Called to clean-up the server.
"""
self.socket.close()
def get_request(self):
"""Get the request and client address from the socket.
"""
return self.socket.accept()
def close_request(self, request):
"""Called to clean up an individual request."""
request.close()
def run(self):
while True:
self.conn,self.client_addr=self.get_request()
print('from client ',self.client_addr)
while True:
try:
head_struct = self.conn.recv(4)
if not head_struct:break
head_len = struct.unpack('i', head_struct)[0]
head_json = self.conn.recv(head_len).decode(self.coding)
head_dic = json.loads(head_json)
print(head_dic)
#head_dic={'cmd':'put','filename':'a.txt','filesize':123123}
cmd=head_dic['cmd']
if hasattr(self,cmd):
func=getattr(self,cmd)
func(head_dic)
except Exception:
break
def put(self,args):
file_path=os.path.normpath(os.path.join(
self.server_dir,
args['filename']
))
filesize=args['filesize']
recv_size=0
print('----->',file_path)
with open(file_path,'wb') as f:
while recv_size < filesize:
recv_data=self.conn.recv(self.max_packet_size)
f.write(recv_data)
recv_size+=len(recv_data)
print('recvsize:%s filesize:%s' %(recv_size,filesize))
tcpserver1=MYTCPServer(('127.0.0.1',8080))
tcpserver1.run()
#下列代码与本题无关
class MYUDPServer:
"""UDP server class."""
address_family = socket.AF_INET
socket_type = socket.SOCK_DGRAM
allow_reuse_address = False
max_packet_size = 8192
coding='utf-8'
def get_request(self):
data, client_addr = self.socket.recvfrom(self.max_packet_size)
return (data, self.socket), client_addr
def server_activate(self):
# No need to call listen() for UDP.
pass
def shutdown_request(self, request):
# No need to shutdown anything.
self.close_request(request)
def close_request(self, request):
# No need to close anything.
pass
import socket
import struct
import json
import os
class MYTCPClient:
address_family = socket.AF_INET
socket_type = socket.SOCK_STREAM
allow_reuse_address = False
max_packet_size = 8192
coding=’utf-8′
request_queue_size = 5
def __init__(self, server_address, connect=True):
self.server_address=server_address
self.socket = socket.socket(self.address_family,
self.socket_type)
if connect:
try:
self.client_connect()
except:
self.client_close()
raise
def client_connect(self):
self.socket.connect(self.server_address)
def client_close(self):
self.socket.close()
def run(self):
while True:
inp=input(“>>: “).strip()
if not inp:continue
l=inp.split()
cmd=l[0]
if hasattr(self,cmd):
func=getattr(self,cmd)
func(l)
def put(self,args):
cmd=args[0]
filename=args[1]
if not os.path.isfile(filename):
print(‘file:%s is not exists’ %filename)
return
else:
filesize=os.path.getsize(filename)
head_dic={‘cmd’:cmd,’filename’:os.path.basename(filename),’filesize’:filesize}
print(head_dic)
head_json=json.dumps(head_dic)
head_json_bytes=bytes(head_json,encoding=self.coding)
head_struct=struct.pack(‘i’,len(head_json_bytes))
self.socket.send(head_struct)
self.socket.send(head_json_bytes)
send_size=0
with open(filename,’rb’) as f:
for line in f:
self.socket.send(line)
send_size+=len(line)
print(send_size)
else:
print(‘upload successful’)
client=MYTCPClient((‘127.0.0.1’,8080))
client.run()
客户端
import socket
import struct
import json
import os
class MYTCPClient:
address_family = socket.AF_INET
socket_type = socket.SOCK_STREAM
allow_reuse_address = False
max_packet_size = 8192
coding='utf-8'
request_queue_size = 5
def __init__(self, server_address, connect=True):
self.server_address=server_address
self.socket = socket.socket(self.address_family,
self.socket_type)
if connect:
try:
self.client_connect()
except:
self.client_close()
raise
def client_connect(self):
self.socket.connect(self.server_address)
def client_close(self):
self.socket.close()
def run(self):
while True:
inp=input(">>: ").strip()
if not inp:continue
l=inp.split()
cmd=l[0]
if hasattr(self,cmd):
func=getattr(self,cmd)
func(l)
def put(self,args):
cmd=args[0]
filename=args[1]
if not os.path.isfile(filename):
print('file:%s is not exists' %filename)
return
else:
filesize=os.path.getsize(filename)
head_dic={'cmd':cmd,'filename':os.path.basename(filename),'filesize':filesize}
print(head_dic)
head_json=json.dumps(head_dic)
head_json_bytes=bytes(head_json,encoding=self.coding)
head_struct=struct.pack('i',len(head_json_bytes))
self.socket.send(head_struct)
self.socket.send(head_json_bytes)
send_size=0
with open(filename,'rb') as f:
for line in f:
self.socket.send(line)
send_size+=len(line)
print(send_size)
else:
print('upload successful')
client=MYTCPClient(('127.0.0.1',8080))
client.run()
平时参数
-
#形参【情势参数】:xx
-
def sendmail(xx,content):
-
import smtplib
-
from email.mime.text import
MIMEText -
from email.utils import formataddr
-
#抓获万分
-
try:
-
msg =
MIMEText(content,’plain’,’utf-8′) -
msg[‘From’] =
formataddr([“Golden”,’发件人地址’]) -
msg[‘To’] =
formataddr([“哈哈”,’收件人地址’]) -
msg[‘Subject’] = “主题”
-
-
server = smtplib.SMTP(“smtp.126.com”,25)
-
server.login(‘发件人地址’,’密码’)
- server.sendmail(‘发件人地址’,[xx],msg.as_string())
-
server.quit()
-
except:
-
#出殡战败
-
return False
-
else:
-
#发送成功
-
return True
-
-
#实际参数:收件人1\收件人2
-
# ret = sendmail(“收件人1”)
-
# ret = sendmail(“收件人2”)
-
-
while
True: -
em = input(“请输入收件人邮箱地址:”)
-
result = sendmail(em,”你好”)
-
if
result == True: -
print(“发送成功”)
-
else:
-
print(“发送失利”)
#!/usr/bin/env python
# encoding: utf-8
暗中认可参数
-
def send(xx,content,hh=”ok”):
-
print(xx,content,hh)
-
print(“发送邮件成功:”,xx,content)
-
return True
-
-
send(“hahaha”,’hello’)
-
send(“hahaha”,’hello’,’bbbb’)
留意:要是急需给某些参数钦赐默许值,该参数必须放在参数列表的最后。
下面附drclient.py
“””
author:haoning
create time:2015.8.1
“””
点名参数
-
def send(xx,content):
-
print(xx,content)
-
return True
-
-
send(“hahaha”,”hello”)
-
send(content=”hahaha”,xx=”hello”)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket, struct, time
from hashlib import md5
import sys
import os
import random
# CONFIG
server = ” #注明服务器地址
username=” #账号
password=” #密码
CONTROLCHECKSTATUS = ‘\x08’
ADAPTERNUM = ‘\x01’
host_ip = ” #ipv4地址
IPDOG = ‘\x01’
host_name = ‘DRCOMFUCKER’
PRIMARY_DNS = ” #DNS服务器
dhcp_server = ” #DHCP服务器
AUTH_VERSION = ‘\x08\x00’
mac = 0xMac地址 #Mac地址
host_os = ‘WINDIAOS’
KEEP_ALIVE_VERSION = ‘\xdc\x02’
AUTH_VERSION = ‘\x0a\x00’
IPDOG = ‘\x01’
# CONFIG_END
nic_name = ” #Indicate your nic, e.g. ‘eth0.2’.nic_name
bind_ip = ‘0.0.0.0’
class ChallengeException (Exception):
def __init__(self):
pass
class LoginException (Exception):
def __init__(self):
pass
def bind_nic():
try:
import fcntl
def get_ip_address(ifname):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(
s.fileno(),
0x8915, # SIOCGIFADDR
struct.pack(‘256s’, ifname[:15])
)[20:24])
return get_ip_address(nic_name)
except ImportError as e:
print(‘Indicate nic feature need to be run under Unix based
system.’)
return ‘0.0.0.0’
except IOError as e:
print(nic_name + ‘is unacceptable !’)
return ‘0.0.0.0’
finally:
return ‘0.0.0.0’
if nic_name != ”:
bind_ip = bind_nic()
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((bind_ip, 61440))
s.settimeout(3)
SALT = ”
IS_TEST = True
# specified fields based on version
CONF = “/etc/drcom.conf”
UNLIMITED_RETRY = True
EXCEPTION = False
DEBUG = False #log saves to file
LOG_PATH = ‘/var/log/drcom_client.log’
if IS_TEST:
DEBUG = True
LOG_PATH = ‘drcom_client.log’
def log(*args, **kwargs):
s = ‘ ‘.join(args)
print s
if DEBUG:
with open(LOG_PATH,’a’) as f:
f.write(s + ‘\n’)
def challenge(svr,ran):
while True:
t = struct.pack(“<H”, int(ran)%(0xFFFF))
s.sendto(“\x01\x02″+t+”\x09″+”\x00″*15, (svr, 61440))
try:
data, address = s.recvfrom(1024)
log(‘[challenge] recv’,data.encode(‘hex’))
except:
log(‘[challenge] timeout, retrying…’)
continue
if address == (svr, 61440):
break
else:
continue
log(‘[DEBUG] challenge:\n’ + data.encode(‘hex’))
if data[0] != ‘\x02’:
raise ChallengeException
log(‘[challenge] challenge packet sent.’)
return data[4:8]
def md5sum(s):
m = md5()
m.update(s)
return m.digest()
def dump(n):
s = ‘%x’ % n
if len(s) & 1:
s = ‘0’ + s
return s.decode(‘hex’)
# def ror(md5, pwd):
# ret = ”
# for i in range(len(pwd)):
# x = ord(md5[i]) ^ ord(pwd[i])
# ret += chr(((x<<3)&0xFF) + (x>>5))
# return ret
def
keep_alive_package_builder(number,random,tail,type=1,first=False):
data = ‘\x07’+ chr(number) + ‘\x28\x00\x0b’ + chr(type)
if first :
data += ‘\x0f\x27’
else:
data += KEEP_ALIVE_VERSION
data += ‘\x2f\x12’ + ‘\x00’ * 6
data += tail
data += ‘\x00’ * 4
#data += struct.pack(“!H”,0xdc02)
if type == 3:
foo = ”.join([chr(int(i)) for i in host_ip.split(‘.’)]) #
host_ip
#CRC
# edited on 2014/5/12, filled zeros to checksum
# crc = packet_CRC(data+foo)
crc = ‘\x00’ * 4
#data += struct.pack(“!I”,crc) + foo + ‘\x00’ * 8
data += crc + foo + ‘\x00’ * 8
else: #packet type = 1
data += ‘\x00’ * 16
return data
# def packet_CRC(s):
# ret = 0
# for i in re.findall(‘..’, s):
# ret ^= struct.unpack(‘>h’, i)[0]
# ret &= 0xFFFF
# ret = ret * 0x2c7
# return ret
def keep_alive2(*args):
#first keep_alive:
#number = number (mod 7)
#status = 1: first packet user sended
# 2: first packet user recieved
# 3: 2nd packet user sended
# 4: 2nd packet user recieved
# Codes for test
tail = ”
packet = ”
svr = server
ran = random.randint(0,0xFFFF)
ran += random.randint(1,10)
# 2014/10/15 add by latyas, maybe svr sends back a file packet
svr_num = 0
packet =
keep_alive_package_builder(svr_num,dump(ran),’\x00’*4,1,True)
while True:
log(‘[keep-alive2] send1’,packet.encode(‘hex’))
s.sendto(packet, (svr, 61440))
data, address = s.recvfrom(1024)
log(‘[keep-alive2] recv1’,data.encode(‘hex’))
if data.startswith(‘\x07\x00\x28\x00’) or
data.startswith(‘\x07’ + chr(svr_num) + ‘\x28\x00’):
break
elif data[0] == ‘\x07’ and data[2] == ‘\x10’:
log(‘[keep-alive2] recv file, resending..’)
svr_num = svr_num + 1
packet =
keep_alive_package_builder(svr_num,dump(ran),’\x00’*4,1, False)
else:
log(‘[keep-alive2] recv1/unexpected’,data.encode(‘hex’))
#log(‘[keep-alive2] recv1’,data.encode(‘hex’))
ran += random.randint(1,10)
packet = keep_alive_package_builder(svr_num,
dump(ran),’\x00’*4,1,False)
log(‘[keep-alive2] send2’,packet.encode(‘hex’))
s.sendto(packet, (svr, 61440))
while True:
data, address = s.recvfrom(1024)
if data[0] == ‘\x07’:
svr_num = svr_num + 1
break
else:
log(‘[keep-alive2] recv2/unexpected’,data.encode(‘hex’))
log(‘[keep-alive2] recv2’,data.encode(‘hex’))
tail = data[16:20]
ran += random.randint(1,10)
packet =
keep_alive_package_builder(svr_num,dump(ran),tail,3,False)
log(‘[keep-alive2] send3’,packet.encode(‘hex’))
s.sendto(packet, (svr, 61440))
while True:
data, address = s.recvfrom(1024)
if data[0] == ‘\x07’:
svr_num = svr_num + 1
break
else:
log(‘[keep-alive2] recv3/unexpected’,data.encode(‘hex’))
log(‘[keep-alive2] recv3’,data.encode(‘hex’))
tail = data[16:20]
log(“[keep-alive2] keep-alive2 loop was in daemon.”)
i = svr_num
while True:
try:
ran += random.randint(1,10)
packet =
keep_alive_package_builder(i,dump(ran),tail,1,False)
#log(‘DEBUG: keep_alive2,packet
4\n’,packet.encode(‘hex’))
log(‘[keep_alive2] send’,str(i),packet.encode(‘hex’))
s.sendto(packet, (svr, 61440))
data, address = s.recvfrom(1024)
log(‘[keep_alive2] recv’,data.encode(‘hex’))
tail = data[16:20]
#log(‘DEBUG: keep_alive2,packet 4
return\n’,data.encode(‘hex’))
ran += random.randint(1,10)
packet =
keep_alive_package_builder(i+1,dump(ran),tail,3,False)
#log(‘DEBUG: keep_alive2,packet
5\n’,packet.encode(‘hex’))
s.sendto(packet, (svr, 61440))
log(‘[keep_alive2] send’,str(i+1),packet.encode(‘hex’))
data, address = s.recvfrom(1024)
log(‘[keep_alive2] recv’,data.encode(‘hex’))
tail = data[16:20]
#log(‘DEBUG: keep_alive2,packet 5
return\n’,data.encode(‘hex’))
i = (i+2) % 0xFF
time.sleep(20)
keep_alive1(*args)
except:
pass
import re
def checksum(s):
ret = 1234
for i in re.findall(‘….’, s):
ret ^= int(i[::-1].encode(‘hex’), 16)
ret = (1968 * ret) & 0xffffffff
return struct.pack(‘<I’, ret)
def mkpkt(salt, usr, pwd, mac):
data = ‘\x03\x01\x00’+chr(len(usr)+20)
data += md5sum(‘\x03\x01’+salt+pwd)
data += usr.ljust(36, ‘\x00’)
data += CONTROLCHECKSTATUS
data += ADAPTERNUM
data +=
dump(int(data[4:10].encode(‘hex’),16)^mac).rjust(6,’\x00′) #mac xor
md51
data += md5sum(“\x01” + pwd + salt + ‘\x00’*4) #md52
data += ‘\x01’ # number of ip
#data += ‘\x0a\x1e\x16\x11’ #your ip address1, 10.30.22.17
data += ”.join([chr(int(i)) for i in host_ip.split(‘.’)])
#x.x.x.x ->
data += ‘\00’*4 #your ipaddress 2
data += ‘\00’*4 #your ipaddress 3
data += ‘\00’*4 #your ipaddress 4
data += md5sum(data + ‘\x14\x00\x07\x0b’)[:8] #md53
data += IPDOG
data += ‘\x00’*4 #delimeter
data += host_name.ljust(32, ‘\x00’)
data += ”.join([chr(int(i)) for i in PRIMARY_DNS.split(‘.’)])
#primary dns
data += ”.join([chr(int(i)) for i in dhcp_server.split(‘.’)])
#DHCP server
data += ‘\x00\x00\x00\x00’ #secondary dns:0.0.0.0
data += ‘\x00’ * 8 #delimeter
data += ‘\x94\x00\x00\x00’ # unknow
data += ‘\x05\x00\x00\x00’ # os major
data += ‘\x01\x00\x00\x00’ # os minor
data += ‘\x28\x0a\x00\x00’ # OS build
data += ‘\x02\x00\x00\x00’ #os unknown
data += host_os.ljust(32,’\x00′)
data += ‘\x00’ * 96
#data += ‘\x01’ + host_os.ljust(128, ‘\x00’)
#data += ‘\x0a\x00\x00’+chr(len(pwd)) # \0x0a represents
version of client, algorithm: DRCOM_VER + 100
#data += ror(md5sum(‘\x03\x01’+salt+pwd), pwd)
data += AUTH_VERSION
data += ‘\x02\x0c’
data += checksum(data+’\x01\x26\x07\x11\x00\x00’+dump(mac))
data += ‘\x00\x00’ #delimeter
data += dump(mac)
data += ‘\x00’ # auto logout / default: False
data += ‘\x00’ # broadcast mode / default : False
data += ‘\xe9\x13’ #unknown, filled numbers randomly =w=
log(‘[mkpkt]’,data.encode(‘hex’))
return data
def login(usr, pwd, svr):
import random
global SALT
i = 0
while True:
salt = challenge(svr,time.time()+random.randint(0xF,0xFF))
SALT = salt
packet = mkpkt(salt, usr, pwd, mac)
log(‘[login] send’,packet.encode(‘hex’))
s.sendto(packet, (svr, 61440))
data, address = s.recvfrom(1024)
log(‘[login] recv’,data.encode(‘hex’))
log(‘[login] packet sent.’)
if address == (svr, 61440):
if data[0] == ‘\x04’:
log(‘[login] loged in’)
break
else:
log(‘[login] login failed.’)
if IS_TEST:
time.sleep(3)
else:
time.sleep(30)
continue
else:
if i >= 5 and UNLIMITED_RETRY == False :
log(‘[login] exception occured.’)
sys.exit(1)
else:
continue
log(‘[login] login sent’)
#0.8 changed:
return data[23:39]
#return data[-22:-6]
def keep_alive1(salt,tail,pwd,svr):
foo = struct.pack(‘!H’,int(time.time())%0xFFFF)
data = ‘\xff’ + md5sum(‘\x03\x01’+salt+pwd) + ‘\x00\x00\x00’
data += tail
data += foo + ‘\x00\x00\x00\x00’
log(‘[keep_alive1] send’,data.encode(‘hex’))
s.sendto(data, (svr, 61440))
while True:
data, address = s.recvfrom(1024)
if data[0] == ‘\x07’:
break
else:
log(‘[keep-alive1]recv/not expected’,data.encode(‘hex’))
log(‘[keep-alive1] recv’,data.encode(‘hex’))
def empty_socket_buffer():
#empty buffer for some fucking schools
log(‘starting to empty socket buffer’)
try:
while True:
data, address = s.recvfrom(1024)
log(‘recived sth unexpected’,data.encode(‘hex’))
if s == ”:
break
except:
# get exception means it has done.
log(‘exception in empty_socket_buffer’)
pass
log(’emptyed’)
def daemon():
with open(‘/var/run/jludrcom.pid’,’w’) as f:
f.write(str(os.getpid()))
def main():
if not IS_TEST:
daemon()
execfile(CONF, globals())
log(“auth
svr:”+server+”\nusername:”+username+”\npassword:”+password+”\nmac:”+str(hex(mac)))
log(bind_ip)
while True:
try:
package_tail = login(username, password, server)
except LoginException:
continue
log(‘package_tail’,package_tail.encode(‘hex’))
#keep_alive1 is fucking bullshit!
empty_socket_buffer()
keep_alive1(SALT,package_tail,password,server)
keep_alive2(SALT,package_tail,password,server)
if __name__ == “__main__”:
main()
from hashlib import sha1
import math
from socket import inet_ntoa
import socket
from struct import pack, unpack
from threading import Timer, Thread
from time import sleep, time
from bencode import bencode, bdecode
from startCrawler import entropy
BT_PROTOCOL = “BitTorrent protocol”
BT_MSG_ID = 20
EXT_HANDSHAKE_ID = 0
def random_id():
hash = sha1()
hash.update(entropy(20))
return hash.digest()
def send_packet(the_socket, msg):
the_socket.send(msg)
def send_message(the_socket, msg):
msg_len = pack(“>I”, len(msg))
send_packet(the_socket, msg_len + msg)
def send_handshake(the_socket, infohash):
bt_header = chr(len(BT_PROTOCOL)) + BT_PROTOCOL
ext_bytes = “\x00\x00\x00\x00\x00\x10\x00\x00”
peer_id = random_id()
packet = bt_header + ext_bytes + infohash + peer_id
send_packet(the_socket, packet)
def check_handshake(packet, self_infohash):
try:
bt_header_len, packet = ord(packet[:1]), packet[1:]
if bt_header_len != len(BT_PROTOCOL):
return False
except TypeError:
return False
bt_header, packet = packet[:bt_header_len],
packet[bt_header_len:]
if bt_header != BT_PROTOCOL:
return False
packet = packet[8:]
infohash = packet[:20]
if infohash != self_infohash:
return False
return True
def send_ext_handshake(the_socket):
msg = chr(BT_MSG_ID) + chr(EXT_HANDSHAKE_ID) +
bencode({“m”:{“ut_metadata”: 1}})
send_message(the_socket, msg)
def request_metadata(the_socket, ut_metadata, piece):
“””bep_0009″””
msg = chr(BT_MSG_ID) + chr(ut_metadata) + bencode({“msg_type”:
0, “piece”: piece})
send_message(the_socket, msg)
def get_ut_metadata(data):
ut_metadata = “_metadata”
index = data.index(ut_metadata)+len(ut_metadata) + 1
return int(data[index])
def get_metadata_size(data):
metadata_size = “metadata_size”
start = data.index(metadata_size) + len(metadata_size) + 1
data = data[start:]
return int(data[:data.index(“e”)])
def recvall(the_socket, timeout=5):
the_socket.setblocking(0)
total_data = []
data = “”
begin = time()
while True:
sleep(0.05)
if total_data and time()-begin > timeout:
break
elif time()-begin > timeout*2:
break
try:
data = the_socket.recv(1024)
if data:
total_data.append(data)
begin = time()
except Exception:
pass
return “”.join(total_data)
def download_metadata(address, infohash, metadata_queue, timeout=5):
metadata = None
start_time = time()
the_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
the_socket.settimeout(timeout)
the_socket.connect(address)
# handshake
send_handshake(the_socket, infohash)
packet = the_socket.recv(4096)
# handshake error
if not check_handshake(packet, infohash):
return
# ext handshake
send_ext_handshake(the_socket)
packet = the_socket.recv(4096)
# get ut_metadata and metadata_size
ut_metadata, metadata_size = get_ut_metadata(packet),
get_metadata_size(packet)
# request each piece of metadata
metadata = []
for piece in range(int(math.ceil(metadata_size/(16.0*1024)))):
#piece是个调节块,依照决定块下载数据
request_metadata(the_socket, ut_metadata, piece)
packet = recvall(the_socket, timeout)
#the_socket.recv(1024*17)
metadata.append(packet[packet.index(“ee”)+2:])
metadata = “”.join(metadata)
except socket.timeout:
pass
except Exception, e:
pass
finally:
#print “metadata= %s” %(metadata)
the_socket.close() #有限支持没回都关闭socket
if metadata != None: #只让不空的种子入?
metadata_queue.put((infohash, address,
metadata,start_time))
实际下载种子还会有一种方法正是借助libtorrent,但那一个太成本cpu了,所以我日常不用她,如下:
动态参数:*
-
def f1(*args):
-
print(args,type(args))
-
-
f1(11,22,33,”haha”,”hello”)
-
-
li = [12,23,33,”hahaha”,”hi”]
-
f1(li)
-
f1(*li)
注意:*默许将盛传的参数全体停放在元组中,f1(*li)。
正文永世更新链接地址:http://www.linuxidc.com/Linux/2016-12/138766.htm
#coding: utf8
import threading
import traceback
import random
import time
import os
import socket
import libtorrent as lt
threading.stack_size(200*1024)
socket.setdefaulttimeout(30)
def fetch_torrent(session, ih, timeout):
name = ih.upper()
url = ‘magnet:?xt=urn:btih:%s’ % (name,)
data = ”
params = {
‘save_path’: ‘/tmp/downloads/’,
‘storage_mode’: lt.storage_mode_t(2),
‘paused’: False,
‘auto_managed’: False,
‘duplicate_is_error’: True}
try:
handle = lt.add_magnet_uri(session, url, params)
except:
return None
status = session.status()
handle.set_sequential_download(1)
meta = None
down_time = time.time()
down_path = None
for i in xrange(0, timeout):
if handle.has_metadata():
info = handle.get_torrent_info()
down_path = ‘/tmp/downloads/%s’ % info.name()
#print ‘status’, ‘p’, status.num_peers, ‘g’,
status.dht_global_nodes, ‘ts’, status.dht_torrents, ‘u’,
status.total_upload, ‘d’, status.total_download
meta = info.metadata()
break
time.sleep(1)
if down_path and os.path.exists(down_path):
os.system(‘rm -rf “%s”‘ % down_path)
session.remove_torrent(handle)
return meta
def download_metadata(address, binhash, metadata_queue, timeout=20):
metadata = None
start_time = time.time()
try:
session = lt.session()
r = random.randrange(10000, 50000)
session.listen_on(r, r+10)
session.add_dht_router(‘router.bittorrent.com’,6881)
session.add_dht_router(‘router.utorrent.com’,6881)
session.add_dht_router(‘dht.transmission.com’,6881)
session.add_dht_router(‘127.0.0.1’,6881)
session.start_dht()
metadata = fetch_torrent(session, binhash.encode(‘hex’),
timeout)
session = None
except:
traceback.print_exc()
finally:
metadata_queue.put((binhash, address, metadata,start_time))
动态参数:字典(**)
-
def f1(**args):
-
print(args,type(args))
-
-
f1(n1=”alex”,kk=18)
-
dic = {‘k1′:’v1′,’k2′:’v2’}
-
f1(**dic)
注意:**暗中同意将盛传的参数全体停放在字典中,f1(**dic)。
万能参数
-
def f1(*args,**kwargs):
-
print(args)
-
print(kwargs)
-
-
f1(11,22,33,44,k1=’v1′,k2=’v2′)
注意:*args,**kwargs顺序无法改换。
动态参数完成format功用
-
s = “i am
{0},age {1}”.format(“alex”,18) -
print(s)
-
-
s1 = “i am
{0},age {1}”.format(*[“alex”,19]) -
print(s1)
-
-
s2 = “i am
{name},age {age}”.format(age=20,name=’alex’) -
print(s2)
-
-
dic ={‘name’:’alex’,’age’:21}
-
s3 = “i am
{name},age {age}”.format(**dic) -
print(s3)
猜一猜输出
-
def f1(a1,a2):
-
print(‘+’)
-
return a1 + a2
-
-
def f1(a1,a2):
-
print(‘*’)
-
return a1 * a2
-
-
ret = f1(8,8)
-
print(ret)
-
def f1(a1):
-
a1.append(999)
-
-
li = [11,22,33,44]
-
f1(li)
-
-
print(li)
细心:函数参数字传送递的是援引。
全局变量
-
NAME = “alex”
-
AGE = 22
-
-
def f1():
-
num = 18
-
NAME = “haha”
-
#修改全局变量:age
-
global AGE
-
AGE = 25
-
print(num,AGE,NAME)
-
-
def f2():
-
num = 19
-
print(num,AGE,NAME)
-
-
f1()
-
f2()
在乎:全局变量重新赋值供给用global,对于列表或字典,可修改,不可重新赋值。定义全局变量全体大写。
函数达成登入与注册
-
def login(username,password):
-
“””
-
用于顾客登入
-
:param username: 顾客输入的顾客名
- :param password: 客户输入的密码
- :return:True,登陆成功;False,登入败北
-
“””
-
f = open(“db”,’r’)
-
#逐行读取
-
for line in f:
-
#用”|”进行分割
-
line_list =
line.strip().split(“|”) -
#特出是不是准确
-
if line_list[0] == username and
line_list[1] == password: -
return True
-
return False
-
-
-
def register(username,password):
-
“””
-
用户注册
-
:param username:用户名
-
:param password:密码
-
:return:默许重回None
-
“””
-
-
f = open(“db”,’a’)
-
temp = “\n”+username + “|” + password
-
f.write(temp)
-
f.close()
-
-
-
def main():
-
t = input(“1:登录;2:注册”)
-
if
t == “1”: -
user = input(“请输入客商名:”)
-
pwd = input(“请输入密码:”)
-
r = login(user,pwd)
-
if r:
-
print(“登陆成功”)
-
else:
-
print(“登陆战败”)
-
elif t == “2”:
-
user = input(“请输入客户名:”)
-
pwd = input(“请输入密码:”)
-
register(user,pwd)
-
-
main()
元正运算(三目运算)
-
if 1
== 1: -
name = “alex”
-
else:
-
name = “golden”
-
-
#地点代码等价于
-
name = “alex” if 1 == 1 else “golden”
lambda表达式
-
def f1(a1):
-
return a1 + 100
-
-
#等价下边包车型客车代码
-
f2 = lambda a1:a1 + 100
-
-
ret = f1(10)
-
print(ret)
-
-
r2 = f2(9)
-
print(r2)
放到函数
-
#abs():取相对值
-
n = abs(-1)
-
print (n)
-
-
#all():全部为真,才为真
-
#any():任何叁个为真,正是真
-
n = all([1,2,3,4,[]])
-
print(n)
-
-
n2 = any([1,[],0,””,None])
-
print(n2)
-
-
#ascii():自动实施对象的 _repr_方法
-
class
Foo: -
def _repr_(self):
-
return “111”
-
n = ascii(Foo())
-
print(n)
-
-
#bin():转二进制
-
#oct():转八进制
-
#hex():转十六进制
-
print(bin(5))
-
print(oct(9))
-
print(hex(15))
-
-
#utf-8 叁个中华夏族民共和国字:三个字节
-
#gbk 二个汉字:二个字节
-
-
#utf-8,一个字节七人,三个中华夏族民共和国字多个字节
-
s = “李杰”
-
#字符串转变字节类型
-
#bytes(需求转移的字符串,依照什么编码)
-
n = bytes(s,encoding=”utf-8″)
-
print(n)
-
n = bytes(s,encoding=”gbk”)
-
print(n)
-
-
#字节转化成字符串
-
new_str = str(bytes(“李杰”,encoding=”utf-8″),encoding=”utf-8″)
-
-
#1、张开文件
-
#只读
-
f = open(‘db’,’r’)
-
#只写,先清空源文件
-
f = open(‘db’,’w’)
-
#文件存在,报错;官样文章,创制并写内容
-
f = open(‘db’,’x’)
-
#追加
-
f = open(‘db’,’a’)
-
#2、操作文件
-
#通过源码查看成效
-
f.read()
-
f.write()
-
-
#3、关闭文件
-
f.close()
-
with open(‘db’) as f:
-
pass
-
-
f = open(‘db’,’r’,encoding=”GBK”)
-
#f = open(‘db’,’r’,encoding=”utf-8″)
-
data = f.read()
-
print(data,type(data))
-
f.close()
-
-
f = open(“db”,”r+”,encoding=”utf-8″)
-
#设若展开形式无b,则read,依照字符读取
-
data = f.read()
-
#获得当前线指挥部针的职位(字节)
-
print(f.tell())
-
print(data)
-
#一抬手一动脚当前线指挥部针到稳固地方(字节)
-
f.seek(1)
-
#如今线指挥部针地点上马向后覆盖
-
f.write(“777”)
-
f.close()
-
-
f = open(‘db’,’rb’)
-
data = f.read()
-
print(data,type(data))
-
-
f = open(‘db’,’ab’)
-
f.write(bytes(“李杰”,encoding=”utf-8″))
-
f.close()
flush()强刷:
-
f = open(“db”,’a’)
-
f.write(“123”)
-
#强制写入
-
f.flush()
-
input(“adsdds”)
readable()查看文件是还是不是可读,重临True或False。
-
f = open(“db”,’w’)
-
print(f.readable())
readline()仅读取一行数据,当文件非常大的时候不至于导致内部存款和储蓄器撑爆。
-
f = open(“db”,’r’)
-
f.readline()
-
f.readline()
truncate()截断,指针后边的数据清空
-
f = open(“db”,’r+’,encoding=”utf-8″)
-
f.seek(3)
-
f.truncate()
-
f.close()
for循环张开的公文对象:
-
f = open(“db”,’r’)
-
for
line in f: -
print(line)
-
f.close()
将文件1的前十行写入文件2:
-
with open(‘db1′,’r’,encoding=”utf-8″) as f1,open(‘db2′,’w’,encoding=”utf-8″) as f2:
-
times = 0
-
for line in f1:
-
times += 1
-
if times <= 10:
-
f2.write(line)
-
else:
-
break
将文件的有个别字符串实行调换:
-
with open(‘db1′,’r’,encoding=”utf-8″) as f1,open(“db2″,’w’,encoding=”utf-8”) as f2:
-
for line in f1:
-
new_str = line.replace(“alex”,”st”)
-
f2.write(new_str)
callable()查看函数是还是不是足以被调用,重临True或False
-
def f1():
-
pass
-
f1()
-
-
f2 = 123
-
-
print(callable(f1))
-
print(callable(f2))
chr()与ord()
-
r = chr(65)
-
n = ord(“B”)
-
print(r,n)
发生1个随机大写字母:
-
import random
-
i = random.randrange(65,91)
-
print(chr(i))
发出6个随机大写字母:
-
import random
-
li = []
-
for i
in range(6): -
temp = random.randrange(65,91)
-
c = chr(temp)
-
li.append(c)
-
result = “”.join(li)
-
print(result)
随便发生字母加数字:
-
import random
-
li = []
-
for i
in range(6): -
r = random.randrange(0,6)
-
if
r == 2 or r == 4: -
num = random.randrange(0,10)
-
li.append(str(num))
-
else:
-
temp = random.randrange(65,91)
-
c = chr(temp)
-
li.append(c)
-
result = “”.join(li)
-
print(result)
compile():将字符串编写翻译成python代码
exec():实施python代码或字符串,无再次来到值
eval():试行表达式,有重临值
-
s = “print(123)”
-
#先编译,single、eval、exec
-
#将字符串编写翻译成python代码
-
r = compile(s,”<string>”,”exec”)
-
print(r)
-
#下一场推行
-
exec(r)
-
-
s = “8*8”
-
ret = eval(s)
-
print(ret)
dir()急迅查看对象提供了何等成效
- print(dir(dict))
divmod()总括商和余数
-
r = divmod(97,10)
-
print(r)
isinstance()判别目的是还是不是是有些类的实例
-
s = [11,22,33]
-
r = isinstance(s,list)
-
print(r)
filter():函数重回True,将成分增添到结果中
map():将函数重回值加多到结果中
将列表中高于22的数输出
-
def f1(args):
-
result = []
-
for item in args:
-
if item > 22:
-
result.append(item)
-
return result
-
-
li = [11,22,33,44,55,66,78]
-
ret = f1(li)
-
print(ret)
filter()实现
-
#filter(函数,可迭代的对象)
-
def f2(a):
-
if
a > 22: -
return True
-
-
li = [11,22,33,44,55,66,78]
-
#filter内部会循环第一个参数,将各个循环元素试行第二个函数,假若函数重返值是True,就增添到ret中
-
ret = filter(f2,li)
-
print(list(ret))
filter()+lambda实现
-
li = [11,22,33,44,55,66,78]
-
ret = filter(lambda a : a > 22,li)
- print(list(ret))
将列表中各种元素加100
-
def f1(args):
-
result = []
-
for i in
args: -
result.append(i+100)
-
return result
-
-
li = [11,22,33,44,55,66,78]
-
r = f1(li)
-
print(list(r))
map()实现
-
#map(函数,可迭代的对象)
-
def f2(a):
-
return a + 100
-
-
li = [11,22,33,44,55,66,78]
-
result = map(f2,li)
-
print(list(result))
map()+lambda实现
-
li = [11,22,33,44,55,66,78]
-
result = map(lambda a : a + 100,li)
- print(list(result))
hash():生成hash值
-
s = “hhhh”
-
print(hash(s))
max():重返最大值
min():重返最小值
sum():返回和
pow():指数计算
-
r = pow(2,10)
-
print(r)
reverse():反转
round():四舍五入
sorted():排序
zip()
-
#赢得字符串 s = “alex_is_good_guy”
-
l1 = [“alex”,22,33,44,55]
-
l2 = [“is”,22,33,44,55]
-
l3 = [“good”,22,33,44,55]
-
l4 = [“guy”,22,33,44,55]
-
-
r = zip(l1,l2,l3,l4)
-
temp = list(r)[0]
-
ret = ‘_’.join(temp)
-
print(ret)
装饰器
s1:
-
def outer():
-
print(“log”)
-
-
def f1():
-
outer()
-
print(“F1”)
-
def f2():
-
outer()
-
print(“F2”)
-
-
def f100():
-
outer()
-
print(“F100”)
b1:
-
import s1
-
-
s2.f1()
-
s2.f2()
-
s2.f100()
装饰器完成
s1:
-
def outer(func):
-
def inner():
-
print(“log”)
-
return func()
-
return inner
-
-
@outer
-
def f1():
-
print(“f1”)
-
-
@outer
-
def f2():
-
print(“f2”)
-
-
@outer
-
def f100():
-
print(“f100”)
b1:
-
import s1
-
-
s2.f1()
-
s2.f2()
-
s2.f100()
在调用函数前后输出内容
-
def outer(func):
-
def inner():
-
print(“log”)
-
ret = func()
-
print(“after”)
-
return ret
-
return inner
求输出内容:
一:
-
def f1():
-
print(“123”)
-
-
def f2(xxx):
-
xxx()
-
-
f2(f1)
二:
-
def f1():
-
print(“123”)
-
-
def f1():
-
print(“234”)
-
-
f1()
传参一:
s1:
-
def outer(func):
-
def inner(a):
-
print(“log”)
-
ret = func(a)
-
print(“after”)
-
return ret
-
return inner
-
-
@outer
-
def f1(arg):
-
print(arg)
-
return “砍你”
b1:
-
import s:1
-
-
s2.f1(“hahahaha”)
参数二:
s1:
-
def outer(func):
-
def inner(*args,**kwargs):
-
print(“log”)
-
ret = func(*args,**kwargs)
-
print(“after”)
-
return ret
-
return inner
-
-
@outer
-
def f1(arg):
-
print(arg)
-
return “砍你”
-
-
@outer
-
def f2(arg1,arg2):
-
print(arg1,arg2)
-
print(“f2”)
b1:
-
import s1
-
-
s2.f1(“hahahaha”)
-
-
s2.f2(“111″,”222”)
询问字符串是或不是满含子字符串:
-
#in方法
-
str = “hsaoiuo kkaoioweioew”
-
if
“iowe” in str: -
print(“存在”)
-
else:
-
print(“不存在”)
-
-
#fand方法
-
str = “hsaoiuo kkaoioweioew”
-
if
str.find(“iowe”) == -1: -
print(“不存在”)
-
else:
- print(“存在”)