Python 网络编程(14) 持续更新

socket 模块

套接字(socket)。包括服务器套接字和客户机套接字。

socket模块中有一个socket类

初始化

import socket
socket.socket(socket.AF_INET,socket.SOCK_STREAM,0)

第一个参数  地址族  第二个参数  流 socket.SOCK_STREAM 或 数据报 socket.SOCK_DGRAM 第三个参数  使用的协议 0

绑定 (bind)

监听 (listen)

listen 参数 允许排队等待的连接数目。

accept 接受客户端连接 (该方法会阻塞)直到客户端连接,返回(client,address)元组,client 客户端套接字,address地址。处理完后,再调用accept方法等待下一个连接,无限循环中。

 

客户端套接字

connect方法连接服务器 参数 和 绑定一样。

 

send 发送数据

recv 接收数据

需要一个 参数 (所需要的最大的字节数)

在Linux或UNIX系统中,只有系统管理员的权限,才可以开1024以下的端口。这些低于1024端口被用于标准服务,如果用Ctrl+C停止服务器,可能要等一段时间,才能使用端口。

socket_server.py

# coding: utf-8

import socket

s = socket.socket()

host = socket.gethostname()
port = 1234
s.bind((host, port))

s.listen(5)
while True:
    client, addr = s.accept()
    print '客户端新连接', addr
    client.send('Thank you connecting')
    client.close()

socket_client.py

# coding: utf-8

import socket

s = socket.socket()

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

 

urllib 和 urllib2 模块

urllib 可以下载Web页面,提取信息。

urllib2 更强大一些,支持 http验证 和 cookie。或者为自己的协议编写扩展程序。

打开远程文件

from  urllib import urlopen

web_page = urlopen('http://www.baidu.com')
web_text = web_page.read()
print web_text

获取远程文件

使用urlretrieve返回一个元组(filename, headers) filename是本地文件名(有urllib自动创建),headers包含远程文件信息

from urllib import urlopen, urlretrieve, urlcleanup

urlretrieve('http://www.baidu.com', 'D:\\python_web_page.html')

urlretrieve 第二个参数 如果不指定文件名,文件会放在临时的位置,用open函数可以打开。完成操作后,可以用 urlcleanup 函数 可以清理临时文件。

其他方法

  • quote                      在特殊的字符串,转成url编码 如 %7E
  • quote_plus              功能和quote差不多,但用+代替空格
  • unquote                       和quote相反
  • unquote_plus               和quote_plus相反
  • urlencode                     把映射(比如字典)或者包含两个元素的元组的序列----(key,value)这种形式----转换为 url编码字符串

其他网络模块

asynchat             asyncore的增强版本

asyncore             异步套接字处理程序

cgi                   基本的CGI支持

cookie               cookie对象操作,主要用于服务器

cookielib               客户端cookie支持

email               email消息支持(包括MIME)

ftplib               FTP客户端模块

gopherlib             gopher客户端模块

httplib               http客户端模块

imaplib IMAP4客户端模块

mailbox              读取几种邮箱的格式

mailcap 通过mailcap文件访问MIME配置

mhlib 访问MH邮箱

nntplib               NNTP客户端模块

poplib               pop客户端模块

robotparser             支持解析WEb服务器的robot文件

SimpleXMLRPCServer         一个简单的XML-RPC服务器

smtpd           SMTP服务器模块

smtpdlib           SMTP客户端模块

telnetlib             Telnet客户端模块

urlparse             支持解析URL

xmlrpclib             XML-RPC客户端支持

 

SocketServer

该模块包括  BaseHttpServer、SimpleHttpServer、CGIHttpServer、SimpleXMLRPCserver、DocXMLRPCServer

SoceketServer包含基本的4个类  

TCP流式套接字 TCPServer

UDP数据报套接字  UDPServer、UnixStreamServer和UnixDatagramServer。

socketserver_test.py

from SocketServer import TCPServer, StreamRequestHandler

class Handler(StreamRequestHandler):

    def handle(self):
        addr = self.request.getpeername()
        print 'Hello',addr
        self.wfile.write('Thank you for connecting')

server = TCPServer(('', 1234), Handler)
server.serve_forever()

多个连接

以上解决方案都是同步的。但是有的时候像完整的聊天会话,需要同时处理多个连接就很重要。

现在有3中方法实现 分叉(forking)、线程(threading)和 异步I/O

分叉是UNIX术语,当分叉一个进程时,基本上是复制了它,并且分叉后的两个进程都从当前的执行点继续运行,并且每个进程都有自己的内存副本(如变量)。一个进程称为父进程,另一个进程(复制的)称为子进程。

在一个使用分叉的服务器中,每一个客户端机连接都利用分叉创造一个子进程。父进程继续监听新的连接,同时子进程处理客户端。当客户端的请求结束时,子进程就退出了。因为分叉的进程时并行运行的,客户端之间不必互相等待。

分叉不支持Window的

因为分叉比较耗资源,又出现另一种方法 线程。

因为线程共享内存,所以必须确保它们的变量不会冲突,或者同一时间修改同一内容,就会造成混乱。

避免线程和分叉的另外一种方法是转换到 Stackless Python 能够在不同的上下文之间快递、方便切换而设计的Python的版本。支持微线程(microthreads)的类线程的并行形式,微线程比真线程的伸缩性好 如 Stackless Python已被用在星战前夜在线(EVE Online)。

 

异步有一个非常强大的异步网络编程框架(Twisted)

forking_test.py

from SocketServer import TCPServer, ForkingMixIn, StreamRequestHandler

class Server(ForkingMixIn, TCPServer):
    pass

class Handler(StreamRequestHandler):

    def handle(self):
        addr = self.request.getpeername()
        print 'Hello', addr
        self.wfile.write('Thank you for connecting')

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

thread_test.py

from SocketServer import TCPServer, ThreadingMixIn, StreamRequestHandler

class Server(ThreadingMixIn, TCPServer):
    pass

class Handler(StreamRequestHandler):

    def handle(self):
        addr = self.request.getpeername()
        print 'Hello', addr
        self.wfile.write('Thank you for connecting')

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

 

带有 select 和 poll 的异步I/O

这两个函数都来自select模块,但它只能在UNIX系统中使用。

select_test.py

import socket, select

s = socket.socket()

host = socket.gethostname()
port = 1234
s.bind((host, port))

s.listen(5)
inputs = [s]

while True:
    rs, ws, es = select.select(inputs, [], [])
    for r in rs:
        if r is s:
            client, addr = s.accept()
            print 'Hello', addr
            inputs.append(client)
        else:
            try:
                data = r.recv(1024)
                disconnected = not data
            except socket.error:
                disconnected = True

            if disconnected:
                print r.getpeername(), 'disconnected'
                inputs.remove(r)
            else:
                print data

poll_test.py

import socket, select

s = socket.socket()

host = socket.gethostname()
port = 1234
s.bind((host, port))

fdmap = {s.fileno(): s}

s.listen(5)
p = select.poll()
p.register(s)
while True:
    events = p.poll()
    for fd, event in events:
        if fd in fdmap:
            c, addr = s.accept()
            print 'Got connection from', addr
            p.register(c)
            fdmap[c.fileno()] = c
        elif event & select.POLLIN:
            data = fdmap[fd].recv(1024)
            if not data: # No data -- connection closed  没有数据关闭连接
                print fdmap[fd].getpeername(), 'disconnected'
                p.unregister(fd)
                del fdmap[fd]
            else:
                print data

 

Twisted事件驱动Python网络框架

Twisted 支持Web服务器、客户机、SSH2、SMTP、POP3、IMAP4、AIM、ICQ、IRC、MSN、Jabber、NNTP和DNS等等。

安装Twisted

从官网下载文件,解压后。运行

python setup.py install

如果发现这个报错

error: Setup script exited with error: Microsoft Visual C++ 9.0 is required (Unable to find vcvarsall.bat). Get it from
http://aka.ms/vcpython27

For Windows installations:

While running setup.py for package installations, Python 2.7 searches for an installed Visual Studio 2008. You can trick Python to use a newer Visual Studio by setting the correct path in VS90COMNTOOLS environment variable before calling setup.py.

If you have Visual Studio 2010 installed, execute

SET VS90COMNTOOLS=%VS100COMNTOOLS%

or with Visual Studio 2012 installed (Visual Studio Version 11)

SET VS90COMNTOOLS=%VS110COMNTOOLS%

or with Visual Studio 2013 installed (Visual Studio Version 12)

SET VS90COMNTOOLS=%VS120COMNTOOLS%

在执行这句前 python setup.py install 先执行以上语句,就解决问题了。

http://www.cnblogs.com/pang1567/p/4168768.html

 

twisted_test.py 

from twisted.internet import reactor
from twisted.internet.protocol import Factory
from twisted.protocols.basic import LineReceiver

class SimpleLogger(LineReceiver):

    def connectionMade(self):
        print 'connection from', self.transport.client

    def connectionLost(self, reason):
        print self.transport.client, 'disconnected'

    def lineReceived(self, line):
        print line

factory = Factory()
factory.protocol = SimpleLogger

reactor.listenTCP(2443, factory)
reactor.run()

 

line_receiver_test.py 每次接收一行数据

from twisted.internet import reactor
from twisted.internet.protocol import Factory
from twisted.protocols.basic import LineReceiver

class SimpleLogger(LineReceiver):

    def connectionMade(self):
        print 'connection from', self.transport.client

    def connectionLost(self, reason):
        print self.transport.client, 'disconnected'

    def dataReceived(self, data):
        print data

factory = Factory()
factory.protocol = SimpleLogger

reactor.listenTCP(2443, factory)
reactor.run()

 

posted @ 2016-08-01 15:28  笨重的石头  阅读(166)  评论(0)    收藏  举报