python 网络编程

来源:互联网 发布:华为数据卡槽不能换 编辑:程序博客网 时间:2024/06/05 04:38

不管哪种语言,都有相对应的网络编程Socket API,如C++的SOCKET,Java的Socket与ServerSocket,当然,Python也不例外,下面看我细细道来。

Python 提供了两个级别访问的网络服务:

  • 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的全部方法。
  • 高级别的网络服务模块 SocketServer, 它提供了服务器中心类,可以简化网络服务器的开发。

Socket

socket()函数

Python 中,我们用 socket()函数来创建套接字,语法格式如下:
socket.socket([family[, type[, proto]]])

参数
- family: 套接字家族可以使AF_UNIX或者AF_INET
- type: 套接字类型可以根据是面向连接的还是非连接分为SOCK_STREAM或SOCK_DGRAM
- protocol: 一般不填默认为0.

Socket 对象(内建)方法
这里写图片描述
这里写图片描述
这里写图片描述
例子
服务器必须进行这些顺序操作来服务:socket(), bind(), listen(), accept() (如果不止一台客户端,可能需要重复 accept() ), 而客户端只需要进行以下序列的操作 socket(), connect().

Demo for TCP:
TCP服务端

import socketimport threadingserver_ip="127.0.0.1"server_port=9999def tcp_server(ip,port):    #建立socket对象    server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)    #绑定ip与port    port = int(port)    server.bind((ip,port))    #监听,最大允许5个进程    server.listen(5)    print "[*] Listing on %s:%d" % (ip,port)    #与多线程的方式处理接入的客户端    while True:        client,addr=server.accept()        print "[*] Accepted connection from:%s:%d" % (addr[0],addr[1])        client_handle=threading.Thread(target=handle_client,args=(client,))        client_handle.start()def handle_client(client):    pass    response=client.recv(1024)    print "[*] Received:%s" % response    #给客户发送一个接收成功提示    client.send("ACK!")if __name__ == '__main__':    tcp_server(server_ip, server_port)

TCP 客户端

import sockettarget_host="127.0.0.1"target_port=9999send_data="GET / HTTP/1.1\r\nHost:%s\r\n\r\n" % target_hostdef tcp_client(host,port,data):    #建立一个socket对象    client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)    #连接服务器    client.connect((host,port))    #向服务器发送数据    client.send(data)    #接收服务器返回的数据    response=client.recv(4096)#最大接收4096字节    print responseif __name__ == '__main__':    #print send_data    tcp_client(target_host, target_port, send_data)

运行结果:
这里写图片描述

Demo for UDP
UDP服务端

import socketimport threadingserver_ip="127.0.0.1"server_port=9999def udp_server(ip,port):    #建立socket对象    server=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)    #绑定ip与port    port = int(port)    server.bind((ip,port))    print "[*] Listing on %s:%d" % (ip,port)    while True:        data,addr=server.recvfrom(1024)        print "[*] Accepted connection from:%s:%d" % (addr[0],addr[1])        print "[*] Received:%s" % data        server.sendto("UDP Connection !",addr)

UDP客户端

import sockettarget_host="127.0.0.1"target_port=9999send_data="GET / HTTP/1.1\r\nHost:%s\r\n\r\n" % target_hostdef udp_client(host,port,data):    #建立一个socket对象    client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)    #连接服务器并发送数据    client.sendto(data,(target_host,target_port))    #接收服务器返回的数据    response=client.recvfrom(4096)[0]    print responseif __name__ == '__main__':    #print send_data    udp_client(target_host, target_port, send_data)

运行结果:
这里写图片描述

Demo for 原始套接字
这里只演示抓取一个数据包,话不多说,直接上代码:

import socketimport oshost = "192.168.1.101"# 创建原始套接字,然后绑定在公开接口上if  os.name == "nt":    socket_protocol = socket.IPPROTO_IPelse:    socket_protocol = socket.IPPROTO_ICMP#使用原始套接字SOCK_RAW创建socket,用于监听网络数据包sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol)   #这里端口为0,监听所有端口sniffer.bind((host,0)) # 设置在捕获的数据包中包含IP头sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)# 在Windows平台上,我们需要设置IOCTL以启用混杂模式if os.name == "nt":    sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)# 读取单个数据包print sniffer.recvfrom(65565)# 在Windows平台上关闭混杂模式if os.name == "nt":    sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)

运行结果:
这里写图片描述

SocketServer

这个类主要是为了简化网络服务器的开发而实现的。它有4个基本的服务器类。

  • SocketServer.TCPServer
    用于TCP协议,提供Client与Server通信。
  • SocketServer.UDPServer
    用于UDP传输,一种基于UPD的网络报文通信。
  • SocketServer.UnixStreamServer
  • SocketServer.UnixDatagramServer
    这两个类用得比较少,与前面TCP、UDP类用法相似。但这两个类只能用在Unix或类Unix系统上。

下面是这4个类的继承与相联关系
+————+
| BaseServer |
+————+
|
v
+———–+ +——————+
| TCPServer |——->| UnixStreamServer |
+———–+ +——————+
|
v
+———–+ +——————–+
| UDPServer |——->| UnixDatagramServer |
+———–+ +——————–+

创建一个Server,通常需要几个步骤:

  1. 创建处理client端请求的BaseRequestHandler子类,并重写handl()方法。在这个方法里面,用于处理client端的请求;
  2. 用服务器地址与端口和BaseRequestHandler子类作为参数实例化一个Serversocket对象
  3. 调用server_close()关闭Serversocket。

Demo for SocketServer.TCPServer
Server端

import SocketServerclass MyTCPHandler(SocketServer.BaseRequestHandler):    #重载handle(),用于处理client端的request    def handle(self):        # self.request是连接cerver端的client socket        self.data = self.request.recv(1024).strip()        print "{} wrote:".format(self.client_address[0])        print self.data        self.request.sendall(self.data.upper())if __name__ == "__main__":    HOST, PORT = "localhost", 9999    # 实例化TCPServer    server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)    server.serve_forever()

Client端

import socketimport sysHOST, PORT = "localhost", 9999data = " ".join(sys.argv[1:])# 实例化client socketsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)try:    # connect服务端并发送数据    sock.connect((HOST, PORT))    sock.sendall(data + "\n")    received = sock.recv(1024)finally:    sock.close()print "Sent:     {}".format(data)print "Received: {}".format(received)

运行结果:
这里写图片描述

Demo for SocketServer.UDPServer
Server端

import SocketServerclass MyUDPHandler(SocketServer.BaseRequestHandler):    #重载handle()用于处理client request    def handle(self):        data = self.request[0].strip()        socket = self.request[1]        print "{} wrote:".format(self.client_address[0])        print data        socket.sendto(data.upper(), self.client_address)if __name__ == "__main__":    HOST, PORT = "localhost", 9999    #实例化UDPServer    server = SocketServer.UDPServer((HOST, PORT), MyUDPHandler)    server.serve_forever()

Client端:

import socketimport sysHOST, PORT = "localhost", 9999data = " ".join(sys.argv[1:])# 实例化UDP client socketsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)#连接Server端并发送数据sock.sendto(data + "\n", (HOST, PORT))received = sock.recv(1024)print "Sent:     {}".format(data)print "Received: {}".format(received)

运行结果:
这里写图片描述

参考链接:
菜鸟笔记:http://www.runoob.com/python/python-socket.html
Python类库文档:http://python.usyiyi.cn/

0 0
原创粉丝点击