0%

Python学习笔记-网络

学会urllib和requests之后,再来学学底层的TCP协议(UDP鸽了)。

客户端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import socket

s = socket.socket() # 创建socket
s.connect(('www.baidu.com', 80))

s.send(b'GET / HTTP/1.1\r\nHost: www.baidu.com\r\nConnection: close\r\n\r\n')

buffer = []
while True:
d = s.recv(1024) # 取出1024字节
if d:
buffer.append(d)
else:
break

s.close() # 关闭socket

data = b''.join(buffer)
header, html = data.split(b'\r\n\r\n', 1)
print(header.decode())
with open('t.html', 'wb') as f: # 保存
f.write(html)

socket.socket(socket.AF_INET, socket.SOCK_STREAM),其中AF_INET指定使用IPv4协议,AF_INET6表示IPv6。SOCK_STREAM指定使用面向流的TCP协议。如无特殊情况可以留空。

使用HTTPS:

1
2
3
4
import ssl

s = ssl.wrap_socket(socket.socket())
s.connect(('www.baidu.com', 443))

服务端

服务端需要打开特定端口监听。一个Socket依赖4项:服务器地址、服务器端口、客户端地址、客户端端口。但是服务器还需要同时相应多个客户端的请求,所以每个连接都需要一个新的进程或线程来处理。

简单的例子,接收客户端连接,把客户端发送的字符串加上Hello再发回去:

服务端

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
import socket
import threading
import time

s = socket.socket()
s.bind(('127.0.0.1', 6666)) # 绑定端口
s.listen(5) # 此socket最多同时与
print('Waiting for connection...')


def tcplink(sock, addr):
print('Accept new connection from %s:%s' % addr)
sock.send(b'Welcome!')
while True:
data = sock.recv(1024) # 读取
time.sleep(1)
if not data or data.decode() == 'exit':
break
sock.send((b'Hello, %s!' % data.decode()).encode())
sock.close()
print('Connection for %s:%s closed' % addr)


while True:
sock, addr = s.accept()
t = threading.Thread(target=tcplink, args=(sock, addr)) # 新建进程
t.start()

客户端:

1
2
3
4
5
6
7
8
9
10
11
12
13
import socket
import random

s = socket.socket()
s.connect(('127.0.0.1', 6666))

print(s.recv(1024).decode())
for i in range(5):
name = chr(random.randint(65, 90))
s.send(name.encode())
print(s.recv(1024).decode())
s.send(b'exit')
s.close()

socketserver库

可以创建TCPServer,UDPServer。方法是定义一个特殊的处理类,继承自BaseRequestHandler,需要实现一个handle()方法。可以调用的变量例如self.client_address,self.server,self.request(对于TCPServer,可以调用self.request.recv/sendall();对于UDPServer,它是一个tuple(data,socket)).为实现方便,可以继承自StreamRequestHandler

实例:返回大写的输入内容

UDP

创建UDP服务器