Python的网络编程(五)

socket的阻塞或同步编程




一、使用socket

网络编程中最基本的部分就是socket(套接字)。socket有两种:服务端socket和客户端 socket。在你创建了一个服务端socket之后,你告诉它去等待连接。然后它将监听某个网络地址(形如:xxx.xxx.xxx.xxx:xxx) 直到客户端连接。然后这两端就可以通信了。

处理客户端socket通常比处理服务端socket要容易一点,因为服务端必须时刻准备处理来自客户端的连接,并且它必须处理多个连接,而客户端只需要简单的连接,然后做点什么,然后断开连接。

实例化一个socket时,可以指定三个参数:地址系列(默认为socket.AF_INET)、流socket(这是个默认值: socket.SOCK_STREAM)或数据报socket(socket.SOCK_DGRAM)、协议(默认值是0)。对于简单的socket,你可以不指定任何参数而全部使用默认值。

服务端socket在使用bind方法之后调用listen方法去监听一个给定的地址。然后,客户端socket就可以通过使用connect方法(connect方法所使用的地址参数与bind相同)去连接服务端。listen方法要求一个参数,这个参数就是等待连接队列中所能包含的连接数。

一旦服务端socket调用了listen方法,就进入了临听状态,然后通常使用一个无限的循环:1、开始接受客房端的连接,这通过调用accept方法来实现。调用了这个方法后将处于阻塞状态(等待客户端发起连接)直到一个客户端连接,连接后,accept返回形如(client,address)的一个元组,其中client是一个用于与客户端通信的socket,address是客户端的形如xxx.xxx.xxx.xxx:xxx的地址;2、然后服务端处理客户端的请求;3、处理完成之后又调用1。

关于传输数据,socket有两个方法:send和recv。send使用字符串参数发送数据;recv参数是字节数,表示一次接受的数据量,如果你不确定一次该接受的数据量的话,最好使用1024。

下面给出一个最小的服务器/客户机的例子:

服务端:

import socket
s = socket.socket()
host = socket.gethostname()
port = 1234
s.bind((host, port))
s.listen(5)
while True:
    c, addr = s.accept()
    print 'Got connection from', addr
    c.send('Thank you for connecting')
    c.close()


客户端:

import socket
s = socket.socket()
host = socket.gethostname()
port = 1234
s.connect((host, port))
print s.recv(1024)


注意:如果你使用Ctrl-C来停止服务端的话,如果再次使用相同的端口可能需要等待一会儿。

二、使用SocketServer

SocketServer模块简单化了编写网络服务器的工作。
它提供了四个基本的服务类:TCPServer(使用TCP协议)、UDPServer(使用数据报)、UnixStreamServer、

UnixDatagramServer。UnixStreamServer和UnixDatagramServer用于类Unix平台。
这四个类处理请求都使用同步的方法,也就是说,在下一个请求处理开始之前当前的请求处理必须已完成

。 

用SocketServer创建一个服务器需要四步:

1、通过子类化BaseRequestHandler类和覆盖它的handle()方法来创建一个请求处理器类,用于处理进来

的请求;
2、实例化服务类如TCPServer,并传递给它参数:服务器地址和请求处理器类;
3、调用服务实例对象的handle_request()或serve_forever()方法去处理请求。

下面使用SocketServer用同步的方法写一个最简单的服务器:

from SocketServer import TCPServer, StreamRequestHandler
#第一步。其中StreamRequestHandler类是BaseRequestHandler类的子类,它为流socket定义了
#rfile和wfile方法
class Handler(StreamRequestHandler):
    def handle(self):
        addr = self.request.getpeername()
        print 'Got connection from', addr
        self.wfile.write('Thank you for connecting')

#第二步。其中''代表运行服务器的主机
server = TCPServer(('', 1234), Handler)
#第三步。serve_forever()导致进入循环状态
server.serve_forever()


注意:使用阻塞或同步的方法一次只能连接一个客户端,处理完成后才能连接下一个客户端。

你可能感兴趣的:(编程,c,socket,python,网络协议)