Python学习(十)

学习网址:廖雪峰的Python教程

网络编程

网络编程就是如何实现两台计算机的通信,互联网时代的到来,现在程序基本都是联网的了,很少有单机类的了,计算机网络就是把各个计算机连接起来,让其在网络中可以通信.

TCP/IP

计算机要想联网,就必须规定通信协议,早起的计算机网络都是些私人的网络协议,互不兼容.为了把全世界的不通类型的计算机连接起来,就要规定一套全球通用的网络通信协议.最重要的两个协议就是TCP和IP协议.

IP协议负责把数据从一台计算机通过网络发送到另一台计算机上.特点是:按块发送,途径多个路由,不能保证到达,不能保证顺序到达.

每台计算机的唯一标示就是IP地址.

TCP协议是建立在IP协议之上的,它负责两台计算机之间建立可靠连接,保证数据包的安全到达,通过三次握手建立连接,对IP包编号,确保对方按顺序收到,如丢包,则自动重发.

IP包除了包含要传输的数据外,还包含源IP地址和目标IP地址,源端口和目标端口

TCP编程

Socket

一个Socket表示’打开了一个网络连接,使用Socket需要知道目标计算机的IP地址和端口,指定协议类型就可以了.

客户端

创建TCP连接时,主动发起连接的叫客户端,被动响应连接的叫服务器.

socket文档

创建一个基于TCP的Socket:

1
2
3
4
5
6
7
8
9
# Echo client program
import socket
HOST = 'daring.cwi.nl' # The remote host
PORT = 50007 # The same port as used by the server
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
s.sendall(b'Hello, world')
data = s.recv(1024)
print('Received', repr(data))

先导入socket包,指定Host,端口号PORT,协议类型:AF_INET代表IPv4协议,AF_INET6表示IPv6协议.SOCK_STREAM指定使用面向流的TCP协议.

sendall()发送数据,recv()接收数据,可以指定接收容量(字节数).close()方法关闭连接.

建立的Socket连接是双向的,双方都可以给对方发送数据.先后顺序由协议来决定.

服务器

服务器进程需要绑定一个端口监听来自其他客户端的连接,如果连接了,就和该客户端建立Socket连接和通信.

一个Socket由服务器地址,服务器端口,客户端地址,客户端端口来确定.服务器需要同时响应多个客户端请求,因此,需要新的进程或线程来处理,否则,服务器一次就只能服务一个客户端.

创建服务器端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Echo server program
import socke
tHOST = '' # Symbolic name meaning all available interfaces
PORT = 50007 # Arbitrary non-privileged port
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
with conn:
print('Connected by', addr)
while True:
data = conn.recv(1024)
if not data: break
conn.sendall(data)

bind()方法绑定地址和端口.listen()方法用来监听端口,参数代表等待连接的数量.

例图:

客户端要主动连接服务器,服务器监听指定端口,对每个新来的连接,创建一个线程或进程来处理.同一个端口,被一个Socket绑定后,就不能被别的Socket绑定了.

UDP编程

UDP与TCP相比,UDP是无连接的协议,不需要建立连接,确定IP地址和端口号就可以发送数据包了,速度快.但不保证是否到达.传输数据不可靠.

创建UDP服务端:
1
2
3
4
5
6
7
8
9
10
11
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定端口:
s.bind(('127.0.0.1', 8973)
print('Bind UDP on 8973...')
while True:
# 接收数据:
data, addr = s.recvfrom(1024)
print('Received from %s:%s.' % addr)
reply = 'Hi, %s!' % data.decode('utf-8')
s.sendto(reply.encode('utf-8'), addr)

SOCK_DGRAM代表Socket是UDP类型,不需要监听端口,recvfrom()返回数据和客户端的地址和端口.

创建UDP客户端:
1
2
3
4
5
6
7
8
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
for data in [b'Stark', b'Captain', b'Thor']:
# 发送数据:
s.sendto(data, ('127.0.0.1', 8973))
# 接收数据:
print(s.recv(1024).decode('utf-8'))
s.close()

不需要连接时才发送,直接发送数据过,recv()方法从服务器接收数据.

例图:


真诚地希望能帮到你!