I plan to study the socket programming of pytho in depth, so I plan to take a look at it and find it difficult to write it well. There are many problems in the middle. It is really easy to read and do.
The source code is as follows:
[Python]
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 \ 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 t:
Pass
If _ name __= = '_ main __':
S = Server ('127. 0.0.1 ', 127)
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 \ 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 t:
Pass
If _ name __= = '_ main __':
S = Server ('127. 0.0.1 ', 127)
S. start ()
In fact, the Http Proxy server itself is not difficult, but it still takes a lot of trouble to write it out. Here we will not elaborate on the source code, it is very simple. I have encountered some problems.
I: I only knew that thread. the first parameter of start_new_thread is a function object. But when I saw the previous blog post, I felt a sigh of relief. This is also acceptable, so I quickly tested it:
[Python]
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 ()
I was disappointed to find that an exception was reported.
[Python]
Unhandled exception in thread started
Error in sys. mongothook:
Original exception was:
Unhandled exception in thread started
Error in sys. mongothook:
Original exception was:
A look, I said, how can the first parameter be an object? I smiled and despised the author a little. So I went to bed, and the next day, I still don't give up, so I went down the code and tried it locally. Yes, I realized I was 2, so I immediately Baidu.
In the original thread module, if the main thread ends before the sub-thread, this exception will be thrown. Therefore, we must end the sub-thread first, the simplest way is to let the main thread sleep for a long enough time. As to how long it will take, it seems that I don't know. How can this problem be solved?
A better solution is that the main thread adds a lock to each sub-thread, the sub-thread releases the lock before the end, and the main thread continuously checks the lock status. The Code is as follows:
[Python]
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 ()
The result is as follows: [python] view plaincopyprint? Hello World
Lock release
Hello World
Lock release
2. The second error is compared to 2.
[Python]
Self. source. send [data]
PeError: 'builtin _ function_or_method 'object is unsubscriptable
Self. source. send [data]
TypeError: 'builtin _ function_or_method 'object is unsubscriptable
I don't know the word unsubscriptable.
The main meaning is that built-in functions or methods cannot have subscripts. You know, the error is very good.