Python公开课 - 网络编程

前言

现在做项目一般都会涉及到网络编程,例如做分布式项目,模块间的彼此调用会用到rest接口,web开发则会涉及到基础的http、https知识。

Python在网络编程这方面,使用起来非常方便。有标准的库可以直接用,也有第三方的强大完善的框架,这些都会在其他章节中进行介绍。

网络模型

首先我们必须了解一下TCP/IP网络模型

网络模型

在教材里面都喜欢用左边这个OSI模型,因为它很规范,但是在实际项目中TCP/IP使用的更加普遍。我们在这里着重介绍这个。

物理层

不用多说,主要是物理线路,可以是以太网,双绞线,光纤等

数据链路层

主要设备包括网桥、交换机、网卡等,涉及到的主要协议为ARP协议,即可以根据IP解析得到物理设备MAC地址的协议

网络层

这层主要是各种路由器,在该层涉及的协议包括IP、ICMP、IGMP、RIP。

IP协议不用多少,主要是用来将源IP的数据包传输给目的IP。

ICMP控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然并不传输用户数据,但是对于用户数据的传递起着重要的作用。例如我们经常使用的ping、tracert命令,就是ICMP协议的应用。

IGMP主要用来做分组广播控制,可以控制将报文发送给对该报文感兴趣的主机。

传输层

这里主要的协议就包括TCP和UDP咯,这两个协议一个是面向连接的,另一个是面向无连接的。

应用层

各种HTTP, FTP,DNS等,都属于应用层的协议了

TCP

服务端例子:

import socketserver
class echorequestserver(socketserver.BaseRequestHandler):
    def handle(self):
        print('服务端启动...')
        conn = self.request
        print('获得连接:', self.client_address)
        while True:
            client_data = conn.recv(1024)
            if not client_data:
                print('断开连接')
                break
            print(client_data.decode('utf-8'))
            print('开始发送...')
            conn.sendall(client_data)

if __name__ == '__main__':
   server =socketserver.TCPServer(("127.0.0.1", 8002),echorequestserver)  # 使用
处理单连接的TCPServer
   server.serve_forever()

客户端例子:

import socket,time
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('127.0.0.1',8002))
while True:
    st = input('input command: ')
    if not st:
        break
    s.send(st.encode('utf-8'))
    echo_back = s.recv(1024)
    print(echo_back.decode('utf-8'))

s.close()

用TCP协议进行Socket编程在Python中十分简单,对于客户端,要主动连接服务器的IP和指定端口,对于服务器,要首先监听指定端口,然后,对每一个新的连接,创建一个线程或进程来处理。通常,服务器程序会无限运行下去。

同一个端口,被一个Socket绑定了以后,就不能被别的Socket绑定了。

UDP

服务端例子:

import socket
BUFSIZE = 1024
ip_port = ('127.0.0.1', 9999)
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # udp协议
server.bind(ip_port)
while True:
    data,client_addr = server.recvfrom(BUFSIZE)
    print('server收到的数据', data)

    server.sendto(data.upper(),client_addr)

server.close()

客户端例子:

import socket
BUFSIZE = 1024
client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
while True:
    msg = input(">> ").strip()
    ip_port = ('127.0.0.1', 9999)
    client.sendto(msg.encode('utf-8'),ip_port)

    data,server_addr = client.recvfrom(BUFSIZE)
    print('客户端recvfrom ',data,server_addr)

client.close()

UDP的使用与TCP类似,但是不需要建立连接。此外,服务器绑定UDP端口和TCP端口互不冲突,也就是说,UDP的9999端口与TCP的9999端口可以各自绑定。

小结

网络编程对所有开发语言都是一样的,Python也不例外。用Python进行网络编程,就是在Python程序本身这个进程内,连接别的服务器进程的通信端口进行通信。

相关阅读