引入
首先了解以下基本概念:
1)计算机网络是把各个计算机连接到一起,让网络中的计算机可以互相通信。
2)网络编程是在程序中实现两台计算机的通信。
3)Python进行网络编程时,实际上是在Python程序本身这个进程内,连接到指定服务器进程的通信端口进行通信,所以网络通信可以看作是两个进程之间的通信。
4)Socket是网络编程的一个抽象概念,通常用一个Socket表示打开了一个网络链接,而打开一个Socket需要知道目标计算机的IP地址和端口号,再指定协议类型即可。
5)python提供两个基本的Socket模块:
- Socket:提供标准的BSD Sockets API。
- SocketServer:提供服务器中心类,可以简化网络服务器的开发。
Socket的格式为:socket (family, type, protocal),分别代表地址族、socket类型 (如下表 图片源自范传辉老师的Python爬虫:开发与项目实战)和协议编号。
Python中常用的Socket函数如下表 (图片源自范传辉老师的Python爬虫:开发与项目实战):
1 TCP编程
网络编程一般包括两部分:服务端和用户端。
TCP是一种面向连接的通信方式,主动发起连接的叫用户端,被动相应连接的叫服务端。
以下代码说明用户端的创建和运行步骤:
# coding: utf-8
import socket
import warnings
warnings.filterwarnings('ignore')
def client():
"""第一步:初始化Socket"""
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
"""第二步:连接目标IP和端口"""
s.connect(('127.0.0.1', 8885))
"""第三步:接受消息"""
print("-->>" + s.recv(1024).decode('utf-8'))
"""第四步:发送消息"""
s.send(b'Hello,I am a client')
print("-->>" + s.recv(1024).decode('utf-8'))
s.send('exit')
"""第五步:关闭"""
s.close()
if __name__ == '__main__':
client()
以下代码用来说明创建和运行TCP服务端的步骤:
# coding: utf-8
import socket, threading, time
import warnings
warnings.filterwarnings('ignore')
def dealClient(sock, addr):
"""第四步: 接受传来的数据,并发送给对方数据"""
print("收到来自%s的信息..." % str(addr))
sock.send(b'Hello,I am server!')
while True:
data = sock.recv(1024)
time.sleep(1)
if not data or data.decode('utf-8') == 'exit':
break
print("-->>%s!" % data.decode('utf-8'))
sock.send(("Loop_Msg: %s!" % data.decode('utf-8')).encode('utf-8'))
"""第五步: 关闭Socket"""
sock.close()
print("已接受,拜拜")
def server():
"""第一步,创建一个基于IPv4和TCP协议的Socket,并进行IP (127.0.0.1为本机IP)和端口绑定"""
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('127.0.0.1', 8885)) # 端口号一致就行
"""第二步:监听连接"""
s.listen(5)
print("我正在快马加鞭,莫方。。。")
while True:
"""第三步:接受一个新连接"""
sock, addr = s.accept()
"""创建新进程来处理TCP连接"""
t = threading.Thread(target=dealClient, args=(sock, addr))
t.start()
if __name__ == '__main__':
server()
首先运行用户端,出现下面这句话:
[WinError 10061] 由于目标计算机积极拒绝,无法连接。
多次尝试无果。。。
于是。。。
先运行服务端,出现我正在快马加鞭,莫方。。。 立马运行用户端,输出如下:
我正在快马加鞭,莫方。。。
收到来自('127.0.0.1', 60631)的信息...
-->>Hello,I am a client!
已接受,拜拜
再运行服务端出现:
OSError: [WinError 10048] 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。
2 UDP编程
TCP通信需要一个建立可靠连接的过程,而且通信双方以流的形式发送数据。UDP则是面向无连接的协议,即只需要知道对方的IP地址和端口号,就能够直接发送数据包,而不关心是否能够到达目的端。这样的话速度挺快的,对于不要求可靠到达的数据,就是他了!
用户端的创建过程如下:
# coding: utf-8
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
for data in [b'boy', b'girl']:
# 发送
s.sendto(data, ('127.0.0.1', 8870))
# 接收
print(s.recv(1024).decode('utf-8'))
s.close()
except:
print('sorry')
服务端:
# coding: utf-8
import socket
"""创建Socket,并进行IP (127.0.0.1为本机IP)和端口绑定"""
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('127.0.0.1', 8870))
print("Bind UDP on 8870...")
while True:
data, addr = s.recvfrom(1024)
print("Received form ", addr)
s.sendto(b'hello, %s'% data, addr)
还是出现了同样的错误,然后用同样的方法处理。。。