Python使用TCPServer编写(多线程)Socket服务
分类:编程应用

SocketServer包对socket包进行了包装(封装),使得创建socket服务非常简单。

1.TCP是一种面向连接的可靠地协议,在一方发送数据之前,必须在双方之间建立一个连接,建立的过程需要经过三次握手,通信完成后要拆除连接,需要经过四次握手,这是由TCP的半关闭造成的,一方在完成数据发送后要发送一个FIN来终止这个方向的连接,一个TCP连接在收到一个FIN后仍能发送数据,但应用程序很少这么做,下面是TCP连接建立和拆除的过程:

TCPServer+BaseRequestHandler

图片 1图片 2

使用TCPServer和BaseRequestHandler编写socket服务的样例。

2.python可以实现TCP服务器和客户端的编程,下面是代码:

[python]  

服务器端:

#-*- coding:utf-8 -*-  

复制代码 代码如下:

  

#!/usr/bin/env python
import socket
host="localhost"
port=10000
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind((host,port))
s.listen(5)
while 1:
 sock,addr=s.accept()
 print "got connection form ",sock.getpeername()
 data=sock.recv(1024)
 if not data:
  break
 else:
  print data

from SocketServer import TCPServer, BaseRequestHandler  

客户端:

import traceback  

复制代码 代码如下:

  

#!/usr/bin/env python
import socket
host="localhost"
port=10000
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((host,port))
s.send("hello from client")
s.close()

class MyBaseRequestHandlerr(BaseRequestHandler):  

3.使用socketserver框架编写TCP服务器

    """ 

    Socketserver模块可以简化网络服务器的编写,它包含了四种服务器类,TCPServer使用TCP协议,UDPServer使用UDP协议,还有两个不常使用的,即UnixStreamServer和UnixDatagramServer,这两个类仅仅在unix环境下有用。

    #从BaseRequestHandler继承,并重写handle方法 

    使用服务器编程,需要进行一下步骤,先建立一个请求句柄类,这个类继承自BaseRequestHandler类,建立这个类后重写它的handle方法,然后实例化服务器类,把主机名,端口号和句柄类传给它,然后调用server_forever()方法来处理请求。

    """  

   使用socketserver框架的服务器:

    def handle(self):  

复制代码 代码如下:

        #循环监听(读取)来自客户端的数据  

import SocketServer
host=''
port=10000
class Handler(SocketServer.StreamRequestHandler):

        while True:  

 def handler(self):
  addr=self.request.getpeername()
  print "got connection from",addr
  self.wfile.write("connected")

            #当客户端主动断开连接时,self.recv(1024)会抛出异常  

server=SocketServer.TCPServer((host,port),Handler)
server.serve_forever()

            try:  

上面的socketserver服务器只能处理一个请求,如果要处理多个请求,可以用forking或者threading实现,实现多进程或者多线程服务器。下面是使用forking和threading的服务器代码:

                #一次读取1024字节,并去除两端的空白字符(包括空格,TAB,r,n)  

使用forking的服务器:

                data = self.request.recv(1024).strip()  

复制代码 代码如下:

                  

from SocketServer import TCPServer,ForkingMixIn,StreamRequestHandler
class Server(ForkingMixIn,TCPServer):pass
class Handler(StreamRequestHandler):

                #self.client_address是客户端的连接(host, port)的元组  

 def handle(self):
  addr=self.request.getpeername()
  print "got connection from",addr
  self.wfile.write('connected')

                print "receive from (%r):%r" % (self.client_address, data)  

server=Server((''.10000),Handler)
server.serve_forever()

                  

使用多线程的服务器:

                #转换成大写后写回(发生到)客户端  

复制代码 代码如下:

                self.request.sendall(data.upper())  

from SocketServer import TCPServer,ThreadingMixIn,StreamRequestHandler
class Server(ThreadingMixIn,TCPServer):pass

            except:  

class Handler(StreamRequestHandler):
 def handle(self):
  addr=self.request.getpeername()
  print "got connection from",addr
  self.wfile.write("connected")

                traceback.print_exc()  

server=Server(('',10000),Handler)
server.serve_forever()

                break  

...

  

if __name__ == "__main__":  

    #telnet 127.0.0.1 9999  

    host = ""       #主机名,可以是ip,像localhost的主机名,或""  

    port = 9999     #端口  

    addr = (host, port)  

      

    #购置TCPServer对象,  

    server = TCPServer(addr, MyBaseRequestHandlerr)  

      

    #启动服务监听  

    server.serve_forever()  

 

TCPServer+StreamRequestHandler

使用TCPServer和StreamRequestHandler编写socket服务的样例。StreamRequestHandler从BaseRequestHandler,并做了封装,使得读写数据更容易。

 

[python] 

#-*- coding:utf-8 -*-  

  

from SocketServer import TCPServer, StreamRequestHandler  

import traceback  

  

class MyStreamRequestHandlerr(StreamRequestHandler):  

    """ 

    #继承StreamRequestHandler,并重写handle方法 

    #(StreamRequestHandler继承自BaseRequestHandler) 

    """  

    def handle(self):  

        while True:  

            #客户端主动断开连接时,self.rfile.readline()会抛出异常  

            try:  

                #self.rfile类型是socket._fileobject,读写模式是"rb",方法有  

                #read,readline,readlines,write(data),writelines(list),close,flush  

                data = self.rfile.readline().strip()  

                print "receive from (%r):%r" % (self.client_address, data)  

                  

                #self.wfile类型是socket._fileobject,读写模式是"wb"  

                self.wfile.write(data.upper())  

            except:  

                traceback.print_exc()  

                break  

  

if __name__ == "__main__":  

    host = ""       #主机名,可以是ip,像localhost的主机名,或""  

    port = 9999     #端口  

    addr = (host, port)  

      

    server = TCPServer(addr, MyStreamRequestHandlerr)  

    server.serve_forever()  

 

 

ThreadingTCPServer+StreamRequestHandler=多线程socket

使用ThreadingTCPServer和StreamRequestHandler编写socket服务的样例。ThreadingTCPServer从ThreadingMixIn和TCPServer继承,实现多线程。

 

[python]  

#-*- coding:utf-8 -*-  

  

from SocketServer import ThreadingTCPServer, StreamRequestHandler  

import traceback  

  

class MyStreamRequestHandlerr(StreamRequestHandler):  

    def handle(self):  

        while True:  

            try:  

                data = self.rfile.readline().strip()  

                print "receive from (%r):%r" % (self.client_address, data)  

                self.wfile.write(data.upper())  

            except:  

                traceback.print_exc()  

                break  

  

if __name__ == "__main__":  

    host = ""       #主机名,可以是ip,像localhost的主机名,或""  

    port = 9999     #端口  

    addr = (host, port)  www.2cto.com

      

    #ThreadingTCPServer从ThreadingMixIn和TCPServer继承  

    #class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass  

    server = ThreadingTCPServer(addr, MyStreamRequestHandlerr)  

    server.serve_forever()  

 

多线程socket效果:

图片 3

TCPServer+BaseRequestHandler 使用TCPServer和BaseRequestHandler编写socket服务的...

本文由正版必中一肖图发布于编程应用,转载请注明出处:Python使用TCPServer编写(多线程)Socket服务

上一篇:系统学习笔记 下一篇:没有了
猜你喜欢
热门排行
精彩图文