抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

本文讲解Python网络编程。

C/S架构

C/S(C:client,S:Server)客户机和服务器结构。Server目的就是等待Client的请求,Client连上Server发送必要的数据,然后等待Server端完成请求的反馈。

C/S网络编程 服务器端进行设置,首先创建一个通信端点,让服务器端能够监听请求,之后就进入等待和处理客户机请求的无限循环中。客户机编程相对服务器简单,只要创建一个通信端点,建立到服务器的连接,就可以提出请求了。

套接字

一种具有之前所说的”通信端点“概念的计算机网络数据结构。网络化的应用程序在开始任何通讯之前都必须创建套接字。

Python支持的Socket:AF_UNIX\AF_NETLINK\AF_INET(基于网络的套接字)

Socket模块

socket模块的socket()函数用来创建套接字:socket(socket_family, socket_type, protocol=0)

创建TCP/IP套接字:tcpsock=socket(socket.AF_INET, socket.SOCK_STREAM)

服务器端套接字函数
函数 描述
s.bind() 绑定地址(主机,端口)到套接字
s.listen() 开始TCP监听
s.accept() 被动接受TCP客户端连接,等待连接的到来
客户端套接字
函数 描述
s.connect() 主动初始化TCP服务器连接
s.connect_ex() Connect函数的扩展版本,出错时返回错误代码,而不是抛出异常
公共用途套接字
函数 描述
s.recv() 接受TCP数据
s.send() 发送TCP数据
s.sendall() 完整发送TCP数据
s.recvfrom() 接受UDP数据
s.sendto() 发送UDP数据
s.getpeemame() 连接到当前套接字的远端地址
s.getsockname() 当前套接字的地址
s.getsockopt() 返回指定套接字的参数
s.setsockopt() 设置指定套接字的参数
s.close() 关闭套接字(创建使用后记得关闭)

网络编程示例

创建一个TCP服务器的流程

1
2
3
4
5
6
7
8
ss = socket.socket() #创建服务器套接字
ss.bind(host,port) # 把地址绑定到套接字上
ss.listen() #设置监听连接
inf_loop: # 服务器无线循环
cs = ss.accept() # 接收客户端连接
common_loop: # 通信循环
cs.recv()/cs.send() # 对话(接收与发送)
cs.close() # 关闭客户端套接字

创建一个TCP客户端的流程

1
2
3
4
5
cs.socket() # 创建客户端套接字
cs.connect() # 尝试连接套接字
common_loop: # 通信循环
cs.recv()/cs.send() #对话(接收与发送)
cs.close() # 关键客户端套接字

编写服务器端脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# server.py
from socket import *
import time

HOST = '127.0.0.1'
PORT = 23342
BUFSIZE = 1024

ADDR = (HOST,PORT)

tcpServer = socket(AF_INET, SOCK_STREAM)
tcpServer.bind(ADDR)
tcpServer.listen(5)

while True:
print('等待连接...')
tcpClient, addr = tcpServer.accept()
print('连接来自:'+ addr)
while True:
data = tcpServer.recv(BUFSIZE)
if not data:
break
tcpClient.send('[%s]%s' % (time.ctime(), data))

tcpClient.close()
tcpServer.close()
1
2
等待连接...
连接来自:('127.0.0.1', 54879)

编写客户端脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# client.py
from socket import *
import time

HOST = '127.0.0.1'
PORT = 23342
BUFSIZE = 1024

ADDR = (HOST,PORT)

tcpClient = socket(AF_INET, SOCK_STREAM)
tcpClient.connect(ADDR)

while True:
data = input('~:')
if not data:
break
tcpClient.send(data)
data = tcpClient.recv(BUFSIZE)
if not data:
break
print(data)

tcpClient.close()
1
2
3
4
~:test
[Mon Apr 13 20:40:30 2020] test
~:nihao
[Mon Apr 13 20:40:40 2020] nihao

编写服务器端脚本(shell版本)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# server.py
from socket import *
import time
from subprocess import Popen, PIPE

HOST = '127.0.0.1'
PORT = 23342
BUFSIZE = 1024

ADDR = (HOST,PORT)

tcpServer = socket(AF_INET, SOCK_STREAM)
tcpServer.bind(ADDR)
tcpServer.listen(5)

while True:
print('等待连接...')
tcpClient, addr = tcpServer.accept()
print('连接来自:'+ addr)
while True:
data = tcpServer.recv(BUFSIZE)
if not data:
break
cmd = Popen(['/bin/bash', '-c', data], stdin=PIPE, stdout=PIPE)
data = cmd.stdout.read()
tcpClient.send('[%s]%s' % (time.ctime(), data))

tcpClient.close()
tcpServer.close()
1
2
等待连接...
连接来自:('127.0.0.1', 54891)

重新执行client.py(在server.py执行后)

1
2
3
~:python3 --version
[Mon Apr 13 21:52:41 2020]
Python 3.8.1

评论