python 网络编程

不管哪种语言,都有相对应的网络编程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 socket
import threading

server_ip="127.0.0.1"
server_port=9999

def 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 socket

target_host="127.0.0.1"
target_port=9999
send_data="GET / HTTP/1.1\r\nHost:%s\r\n\r\n" % target_host

def 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 response

if __name__ == '__main__':
    #print send_data
    tcp_client(target_host, target_port, send_data)

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

Demo for UDP
UDP服务端

import socket
import threading
server_ip="127.0.0.1"
server_port=9999

def 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 socket

target_host="127.0.0.1"
target_port=9999
send_data="GET / HTTP/1.1\r\nHost:%s\r\n\r\n" % target_host

def 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 response
if __name__ == '__main__':
    #print send_data
    udp_client(target_host, target_port, send_data)

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

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

import socket
import os

host = "192.168.1.101"

# 创建原始套接字,然后绑定在公开接口上
if  os.name == "nt":
    socket_protocol = socket.IPPROTO_IP
else:
    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 SocketServer

class 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 socket
import sys

HOST, PORT = "localhost", 9999
data = " ".join(sys.argv[1:])

# 实例化client socket
sock = 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 SocketServer

class 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 socket
import sys

HOST, PORT = "localhost", 9999
data = " ".join(sys.argv[1:])

# 实例化UDP client socket
sock = 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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值