分类 Python 下的文章

Python socket tcp

Server

#!/usr/bin/python

'''
	tcp socket server
'''

import sys
import socket

HOST = ''  
PORT = 9243
DATA_BUFFER = 4096

# create a TCP socket
try :
	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
	print 'Socket created'
except socket.error, msg :
	print 'Failed to create socket. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
	sys.exit()

# Bind socket to local host and port
try:
	s.bind((HOST, PORT))
except socket.error , msg:
	print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
	sys.exit()

s.listen(5)			# allow 5 simultaneous

while True:
	# wait for next client to connect
	connection, address = s.accept()		# connection is a new socket
	while True:
		data = connection.recv(DATA_BUFFER) # receive up to 1K bytes
		if data:
			print data
		else:
			break
	connection.close()						# close socket

Client


#!/usr/bin/python

'''
	tcp socket client
'''

import socket  
  
address = ('223.4.238.138', 9243) 
# create a TCP socket
try :
	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
	print 'Socket created'
except socket.error, msg :
	print 'Failed to create socket. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
	sys.exit()	

# create a TCP socket
try :
	s.connect(address)
	print 'Connect successfully'
except socket.error, msg :
	print 'Failed to Connect . Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
	sys.exit()

s.send('hello world')  

s.close()  

Python open模式

open(file_name,mode)

w 以写方式打开,
a 以追加模式打开 (从 EOF 开始, 必要时创建新文件)
r+ 以读写模式打开
w+ 以读写模式打开 (参见 w )
a+ 以读写模式打开 (参见 a )
rb 以二进制读模式打开
wb 以二进制写模式打开 (参见 w )
ab 以二进制追加模式打开 (参见 a )
rb+ 以二进制读写模式打开 (参见 r+ )
wb+ 以二进制读写模式打开 (参见 w+ )
ab+ 以二进制读写模式打开 (参见 a+ )

注意:

1、使用'w',文件若存在,首先要清空,然后(重新)创建,
2、使用'a'模式 ,把所有要写入文件的数据都追加到文件的末尾,即使你使用了seek()指向文件的其他地方,如果文件不存在,将自动被创建。

Python 发送HEAD包

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import urllib2
import socket

def send(url):
	request = urllib2.Request(url,)
	try:
		request.get_method = lambda: 'HEAD'
		response = urllib2.urlopen(request)
		msg = response.msg
		print "message : %s"%msg
		headers = response.headers
		print "\n\n%s"%headers
		data = response.read()
		print "data\n%s"%data
	except urllib2.HTTPError,e:
		code = e.code
		print code
	except Exception,e:
		print e

socket.setdefaulttimeout(2)
send("http://74.91.23.207/")

Head方法要求响应与GET请求一样,但是没有响应体(response body)。如果我们只对关于网页或资源的
信息感兴趣,而不想检索资源本身的全部内容,可以使用HEAD命令。HEAD的使用方法与GET相同,只是不返
回Web页的正文内容。

Python Mysql类

Python支持Mysql的库

# yum -y install  MySQL-python

import MySQLdb

mysql_instance = "";
class MySQLHelper:
	def __init__(self,host,user,password,db_name,charset="utf8"):
		self.host = host
		self.user = user
		self.password = password
		self.db_name = db_name
		self.charset = charset
		try:
			self.conn = MySQLdb.connect(host=self.host,user=self.user,passwd=self.password,db=self.db_name, charset=self.charset)
		except:
			print("Mysql Connect Error ")
			sys.exit(0)

	def update_sql_cmd(self,sql_cmd):
		self.cur = self.conn.cursor()
		try :
			self.cur.execute(sql_cmd)
			self.conn.commit()
			self.cur.close()
			return True
		except Exception, e:
			print "[MYSQL ERROR] : %s"%sql_cmd
			self.cur.close()
			return False

	def run_sql_cmd(self,sql_cmd):
		try :
			self.cur = self.conn.cursor()
			self.cur.execute(sql_cmd)
			res = self.cur.fetchall()
			self.cur.close()
			return res
		except Exception, e:
			print "[MYSQL ERROR] : %s"%sql_cmd
			self.cur.close()
			return False

	def close(self):
		self.conn.close()

def mysql_init():
	'''connect to mysql database opencdn'''
	try:
		global mysql_instance
		mysql_instance = MySQLHelper(mysql_host,mysql_username,mysql_password,mysql_dbname)
	except Exception, e:
		print("Mysql Error %d: %s" % (e.args[0], e.args[1]))
		sys.exit(1)

update_sql_cmd()可以对mysql进行插入操作
run_sql_cmd()可以对mysql查询操作并且返回二元组

Python单位转化

[php]
def b2h(n):
symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
prefix = {}
for i, s in enumerate(symbols):
prefix[s] = 1 << (i+1)*10
for s in reversed(symbols):
if n >= prefix[s]:
value = float(n) / prefix[s]
return '%.1f%s' % (value, s)
return "%sB" % n
[/php]

python进程池

python自2.6开始提供了多进程模块multiprocessing,进程池使用multiprocessing.pool,pool的构造如下:

```
multiprocessing.Pool([processes[, initializer[, initargs[, maxtasksperchild]]]])
```

* processes: 表示pool中进程的数目,默认地为当前CPU的核数。
* initializer: 表示新进程的初始化函数。
* initargs: 表示新进程的初始化函数的参数。
* maxtasksperchild: 表示每个进程执行task的最大数目

```
apply_async(func[, args[, kwds[, callback]]])
```

主进程循环运行过程中不等待apply_async的返回结果,在主进程结束后,即使子进程还未返回整个程序也会退出。虽然 apply_async是非阻塞的,但其返回结果的get方法却是阻塞的,如使用result.get()会阻塞主进程。
如果我们对返回结果不感兴趣, 那么可以在主进程中使用pool.close与pool.join来防止主进程退出。注意join方法一定要在close或terminate之后调用。

```
#!/usr/bin/python
# -*- coding: UTF-8 -*-

import os
import multiprocessing
import time

def func(msg):
print msg,os.getpid()
time.sleep(1)
return "done" + msg

if __name__ == "__main__":
pool = multiprocessing.Pool(processes=12)
result = []
for i in xrange(10):
msg = "hello %d" %(i)
result.append(pool.apply_async(func, (msg, )))
pool.close()
pool.join()
print "wait"
for res in result:
print res.get()
print "Sub-process done.";
```

python HTTP请求包

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import urllib2
import socket

def send(url,host,body=""):
	socket.setdefaulttimeout(2)
	request = urllib2.Request(url,body)
	request.add_header('User-Agent', 'Firefox')
	request.add_header('Cache-Control', 'no-cache')
	request.add_header('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.7')
	request.add_header('Referer', "http://www.firefoxbug.com/")
	request.add_header('Keep-Alive',60)
	request.add_header('Connection', 'keep-alive')
	request.add_header('Host',host)
	try:
		response = urllib2.urlopen(request)
		code = response.code
		msg = response.msg
		print "status code %d"%code
		print "message : %s"%msg

		headers = response.headers
		print "\n\n%s"%headers

		data = response.read()
		print "data\n%s"%data
	except Exception,e:
		raise e

send("http://223.4.238.138","www.firefoxbug.net")

是否发送Post包可以通过Body字段是否为空来指定。

socket.setdefaulttimeout()来指定请求超时时间。

python线程池

线程池的概念简单理解就是很多线程的列表,一般线程池和任务队列相结合。一个任务队列是FIFO的,主线程负责所有进程的管理,生成一个子线程(一个子进程或者线程池)对队列进行任务输入,任务的输出端可以是线程池。由主线程进行调度,根据线程ID分配任务。

- 阅读剩余部分 -

base64编码

By firefoxbug

shell base64编码


[root@firefoxbug] str="hello world"

[root@firefoxbug] echo -n "$str" | base64

aGVsbG8gd29ybGQ=

[root@firefoxbug] echo "$str" | base64 注意要加 -n ,不然会有换行,编码就有问题了。

aGVsbG8gd29ybGQK

shell base64解码


-d :decode

[root@firefoxbug]  echo -n "$str" | base64 | base64 -d

hello world

python base64编码


[code]
#!/usr/bin/python
#-*-coding:utf-8-*-

import base64
sour_str = "hello world"
print base64.encodestring(sour_str)
[/code]

python base64解码


[code]
#!/usr/bin/python
#-*-coding:utf-8-*-

import base64
sour_str = "hello world"
decode_str = base64.encodestring(sour_str)
print base64.decodestring(decode_str)
[/code]

python监听端口

监听tcp协议的端口包

#!/usr/bin/python

import socket

HOST = 'localhost'   # use '' to expose to all networks
PORT = 515

def incoming(host, port):
    """Open specified port and return file-like object"""
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.bind((host, port))
    sock.listen(0)
    request, addr = sock.accept()
    return request.makefile('r', 0)

for line in incoming(HOST, PORT):
    print line,

监听udp协议的端口包

#!/usr/bin/python

# receive udp packets from all interfaces

import socket

HOST = ''   # use '' to expose to all networks
port = 515

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((HOST, port))

try:
    while True:
            data, addr = s.recvfrom(4096)
            back = 'Your address is %r\n' % (addr,)
            print data
except KeyboardInterrupt:
    print()

python json

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解

析和生成。json默认应该是在python 2.6以上。

对简单数据类型的encoding 和 decoding:

使用简单的json.dumps方法对简单数据类型进行编码,例如:

[python]
import json

obj = [[1,2,3],123,123.123,'abc',{'key1':(1,2,3),'key2':(4,5,6)}]
encodedjson = json.dumps(obj)
print repr(obj)
print encodedjson
[/python]

输出:

[python]
[[1, 2, 3], 123, 123.123, 'abc', {'key2': (4, 5, 6), 'key1': (1, 2, 3)}]
[[1, 2, 3], 123, 123.123, "abc", {"key2": [4, 5, 6], "key1": [1, 2, 3]}]
[/python]

json decoding

[python]
decodejson = json.loads(encodedjson)
[/python]

问题


[python]
>>> str = '["hello\"world","hello\"world"]'
>>> json.loads(str)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/json/__init__.py", line 326, in loads
return _default_decoder.decode(s)
File "/usr/lib/python2.7/json/decoder.py", line 366, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python2.7/json/decoder.py", line 382, in raw_decode
obj, end = self.scan_once(s, idx)
ValueError: Expecting , delimiter: line 1 column 8 (char 8)
>>> print str
["hello"world","hello"world"]
[/python]

问题就是出现在上面,用反斜杆转义了双引号,结果赋值的时候 str 的结构就变了,json就没法识别了,所

以只能用双斜杆,

[python]
>>> str = '["hello\\"world","hello\\"world"]'
>>> json.loads(str)
[u'hello"world', u'hello"world']
>>> print str
["hello\"world","hello\"world"
[/python]

原本是想用json先将日志格式化之后,通过syslog-ng传递到另外机器上,syslog-ng对接的是管道,从管道

里用 read 命令读取的到变量里面,因为 read 命令其实就是一个变量赋值的过程,所以赋值过程中的单斜

干都被shell吃了,解决方案就是要么换成双斜杆,不过这吃力不讨好,最好的办法呢? read 命令加个参

数 "-r",这样read就做变量赋值的时候就会屏蔽所有的反斜杆。

python paramiko模块安装和使用

简介


大家会发现,常见的解决方法都会需要对远程服务器必要的配置,如果远程服务器只有一两台还好说,如果有N台,还需要逐台进行配置,或者需要使用代码进行以上操作时,上面的办法就不太方便了。

使用paramiko可以很好的解决以上问题,比起前面的方法,它仅需要在本地上安装相应的软件(python以及PyCrypto),对远程服务器没有配置要求,对于连接多台服务器,进行复杂的连接操作特别有帮助。

- 阅读剩余部分 -

python限制子进程运行时间

想在python中限制子进程的运行时间,于是想到了定时器。下面是两种实现方法,具体的进程执行时间

可以调整。先看代码

#!/usr/bin/python

# limit time of subprocess running by set a timer

import os
import time
import signal
import threading

class Timer(threading.Thread):
	"""
	very simple but useless timer.
	"""
	def __init__(self, seconds):
		self.runTime = seconds
		self.process = []
		threading.Thread.__init__(self)
	def run(self):
		time.sleep(self.runTime)
		print "Time's up!"
		for pid in self.process:
			print "now kill process %d"%pid
			os.kill(pid,signal.SIGKILL)


def child():
	while True:
		print ("Child process",os.getpid())
		time.sleep(1)

if __name__ == '__main__':
	test = Timer(2)
	test.start()

	for i in range(5):
		newpid = os.fork()
		if newpid == 0:
			child()
		else:
			test.process.append(newpid)
			print ("Parent process ",os.getpid(),newpid)

- 阅读剩余部分 -

Linux下信号和sleep()

今天在写python的过程中碰到一个比较奇怪的问题,先看代码,定义了一个信号,加了一个计时器.

import time
import signal

def catcher(signum,_):
    print "beat !"

signal.signal(signal.SIGALRM, catcher)
signal.setitimer(signal.ITIMER_REAL,1, 2)

while True:
    print "hello"
    time.sleep(5)

程序一执行,输出的结果很奇怪

- 阅读剩余部分 -

python多线程编程

python多线程

传入函数创建线程

#!/usr/bin/python

import os
import sys
import time
import signal
import threading

def timer(no, interval):
    cnt = 0
    while cnt<10:
        print 'Thread:(%d) Time:%s/n'%(no, time.ctime())
        time.sleep(interval)
        cnt += 1

if __name__ == '__main__':
    #Initialize a thread object, passing in the function timer, and its parameters
    th1 = threading.Thread(target=timer, args=(1,1));
    th2 = threading.Thread(target=timer, args=(2,2));

    #Start thread
    th1.start()
    th2.start()

    #Main thread waits until child threads exit,without threading.join(),the main thread will exit even the child
    #threads is still running
    th1.join()
    th2.join()
    print "main thread exit..."

继承类创建线程

#!/usr/bin/python

import os
import sys
import threading
import signal
import time

class timer(threading.Thread): #The timer class is derived from the class threading.Thread
    def __init__(self, num, interval):
        threading.Thread.__init__(self)
        self.thread_num = num
        self.interval = interval
        self.thread_stop = False

    def run(self): #Overwrite run() method, put what you want the thread do here
        while not self.thread_stop:
            print 'Thread Object(%d), Time:%s' %(self.thread_num, time.ctime())
            time.sleep(self.interval)
            
    def stop(self):
        self.thread_stop = True

if __name__ == '__main__':
    Watcher()
    thread1 = timer(1, 1)
    thread2 = timer(2, 2)
    thread1.start()
    thread2.start()
    thread1.join()
    thread2.join()
    print "main thread exit..."

上面的程序在会出现无法响应ctrl + C 的情况,导致程序无法退出,可以加入一个Watcher的监控进程,来捕捉 ctrl + c的信号, 只需把Watcher()在线程创建之前调用即可.

class Watcher:
    def __init__(self):
        """ Creates a child thread, which returns.  The parent
            thread waits for a KeyboardInterrupt and then kills
            the child thread.
        """
        self.child = os.fork()
        if self.child == 0:
            return
        else:
            self.watch()

    def watch(self):
        try:
            os.wait()
        except KeyboardInterrupt:
            print ' exit...'
            self.kill()
        sys.exit()

    def kill(self):
        try:
            os.kill(self.child, signal.SIGKILL)
        except OSError:
            pass

python多线程有个限制,全局解释器锁(global interpreter lock),这个锁的意思是任一时间只能有一个线程使用解释器,跟单cpu跑多个程序一个意思,大家都是轮着用的,这叫“并发”,不是“并行”。手册上的解释是为了保证对象模型的正确性!这个锁造成的困扰是如果有一个计算密集型的线程占着cpu,其他的线程都得等着....,试想你的多个线程中有这么一个线程,得多悲剧,多线程生生被搞成串行;当然这个模块也不是毫无用处,手册上又说了:当用于IO密集型任务时,IO期间线程会释放解释器,这样别的线程就有机会使用解释器了!所以是否使用这个模块需要考虑面对的任务类型。

python IP地址转换

 IP地址从点分十进制到整型转换:


[code]
import socket
import struct

print struct.unpack("!L",socket.inet_aton("192.168.1.1"))[0]
[/code]

 IP地址从整型到点分十进制转换:


[code]
import socket
import struct

print socket.inet_ntoa(struct.pack("!L",integer)
[/code]

python 长整型L

>>> "Hello, world!"
'Hello, world!'
>>> 1000L
1000L
>>> #字符串是被单引号括起来的,长整型结尾有L。这是因为Python打印值的时候会保持该值在Python代码中的状态,而不是希望用户看到的状态,如果使用了print语句,结果就不一样了:
>>> print "Hello, world!"
Hello, world!
>>> print 1000L
1000
>>>

当你想知道一个变量的值是多少时,也可能会对它的整形还是长整形感兴趣。可以使用两个函数来实现这一需求:

str函数:会把值转换为合理的形式字符串,以便用户理解。
repr函数:会创建一个字符串,它以合法的Python表达式来表示: