最近打算好好深入研究下python的socket编程, 于是打算学习下,仿写了一下,发现写好还真不容易,中途出现很多问题,果真是看的容易,做起来难啊
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
import socket import thread import urlparse import select BUFLEN = 8192 class Proxy( object ): def __init__( self ,conn,addr): self .source = conn self .request = "" self .headers = {} self .destnation = socket.socket(socket.AF_INET,socket.SOCK_STREAM) self .run() def get_headers( self ): header = '' while True : header + = self .source.recv(BUFLEN) index = header.find( '\n' ) if index > 0 : break #firstLine,self.request=header.split('\r\n',1) firstLine = header[:index] self .request = header[index + 1 :] self .headers[ 'method' ], self .headers[ 'path' ], self .headers[ 'protocol' ] = firstLine.split() def conn_destnation( self ): url = urlparse.urlparse( self .headers[ 'path' ]) hostname = url[ 1 ] port = "80" if hostname.find( ':' ) > 0 : addr,port = hostname.split( ':' ) else : addr = hostname port = int (port) ip = socket.gethostbyname(addr) print ip,port self .destnation.connect((ip,port)) data = "%s %s %s\r\n" % ( self .headers[ 'method' ], self .headers[ 'path' ], self .headers[ 'protocol' ]) self .destnation.send(data + self .request) print data + self .request def renderto( self ): readsocket = [ self .destnation] while True : data = '' (rlist,wlist,elist) = select.select(readsocket,[],[], 3 ) if rlist: data = rlist[ 0 ].recv(BUFLEN) if len (data)> 0 : self .source.send(data) else : break def run( self ): self .get_headers() self .conn_destnation() self .renderto() class Server( object ): def __init__( self ,host,port,handler = Proxy): self .host = host self .port = port self .server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) self .server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1 ) self .server.bind((host,port)) self .server.listen( 5 ) self .handler = handler def start( self ): while True : try : conn,addr = self .server.accept() thread.start_new_thread( self .handler,(conn,addr)) except : pass if __name__ = = '__main__' : s = Server( '127.0.0.1' , 8080 ) s.start() import socket import thread import urlparse import select BUFLEN = 8192 class Proxy( object ): def __init__( self ,conn,addr): self .source = conn self .request = "" self .headers = {} self .destnation = socket.socket(socket.AF_INET,socket.SOCK_STREAM) self .run() def get_headers( self ): header = '' while True : header + = self .source.recv(BUFLEN) index = header.find( '\n' ) if index > 0 : break #firstLine,self.request=header.split('\r\n',1) firstLine = header[:index] self .request = header[index + 1 :] self .headers[ 'method' ], self .headers[ 'path' ], self .headers[ 'protocol' ] = firstLine.split() def conn_destnation( self ): url = urlparse.urlparse( self .headers[ 'path' ]) hostname = url[ 1 ] port = "80" if hostname.find( ':' ) > 0 : addr,port = hostname.split( ':' ) else : addr = hostname port = int (port) ip = socket.gethostbyname(addr) print ip,port self .destnation.connect((ip,port)) data = "%s %s %s\r\n" % ( self .headers[ 'method' ], self .headers[ 'path' ], self .headers[ 'protocol' ]) self .destnation.send(data + self .request) print data + self .request def renderto( self ): readsocket = [ self .destnation] while True : data = '' (rlist,wlist,elist) = select.select(readsocket,[],[], 3 ) if rlist: data = rlist[ 0 ].recv(BUFLEN) if len (data)> 0 : self .source.send(data) else : break def run( self ): self .get_headers() self .conn_destnation() self .renderto() class Server( object ): def __init__( self ,host,port,handler = Proxy): self .host = host self .port = port self .server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) self .server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1 ) self .server.bind((host,port)) self .server.listen( 5 ) self .handler = handler def start( self ): while True : try : conn,addr = self .server.accept() thread.start_new_thread( self .handler,(conn,addr)) except : pass if __name__ = = '__main__' : s = Server( '127.0.0.1' , 8080 ) s.start() |
其实Http代理服务器本身不难,但写出来还是挺费事的,这里就不细说源代码了,很简单。主要说说,我遇到的问题。
一: 我本来只知道,thread.start_new_thread的第一个参数是函数对象,但当我看到上面的博文时,心里一愣,这样也可以,于是我迅速的测试了一下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
import thread class Hello: def __init__( self ,content): print content def cs(): thread.start_new_thread(Hello, ( "Hello World" ,)) if __name__ = = '__main__' : cs() import thread class Hello: def __init__( self ,content): print content def cs(): thread.start_new_thread(Hello, ( "Hello World" ,)) if __name__ = = '__main__' : cs() |
Unhandled exception in thread started by
Error in sys.excepthook:
Original exception was:
Unhandled exception in thread started by
Error in sys.excepthook:
Original exception was:
一看,我说嘛,第一个参数怎么可以是对象,我呵呵一笑,稍微鄙视了一下作者。于是,我洗洗睡了,第二天,我还是不死心,于是把代码下下来,本地实验了一下,可以的,立马意识到是我2了,于是立马百度。
原来thread模块中,主线程如果比子线程先结束,就会抛出这个异常,所以我们必须让子线程先结束,最简单的方法就是让主线程sleep足够长的时间,至于多长时间,貌似不知道,那到底怎么解决呢?
比较好的解决办法就是,主线程给每个子线程都加一把锁,子线程在结束前将锁释放掉,主线程一直循环检查锁的状态。代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
import thread class Hello: def __init__( self ,content,lock): print content """ do something .... At the end,release the lock """ lock.release() def cs(): lock = thread.allocate_lock() lock.acquire() thread.start_new_thread(Hello, ( "Hello World" ,lock)) while True : if not lock.locked(): break print "lock release" if __name__ = = '__main__' : cs() import thread class Hello: def __init__( self ,content,lock): print content """ do something .... At the end,release the lock """ lock.release() def cs(): lock = thread.allocate_lock() lock.acquire() thread.start_new_thread(Hello, ( "Hello World" ,lock)) while True : if not lock.locked(): break print "lock release" if __name__ = = '__main__' : cs() |
二.第二个错误就是比较2的了
self.source.send[data]
peError: ‘builtin_function_or_method’ object is unsubscriptable
self.source.send[data]
TypeError: ‘builtin_function_or_method’ object is unsubscriptable
主要意思就是说,内置函数或方法无法拥有下标,你懂的
暂无评论内容