1、tcp客户端
import socket
# 1、创建客户端套接字对象(IPv4:socket.AF_INET, TCP:socket.SOCK_STREAM)
tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2、和服务器端建立套接字连接
tcp_client_socket.connect(('192.168.15.62', 8080))
# 3、发送数据到服务器端
data = '?'.encode('gbk')
tcp_client_socket.send(data)
# 4、接收服务器端返回的数据
recv_data = tcp_client_socket.recv(1024).decode('gbk')
print(f'服务器端响应:{recv_data}')
# 5、关闭连接
tcp_client_socket.close()
2、tcp服务器端
import socket
# 创建服务端套接字对象
tcp_sever_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设置端口号复用,让程序退出端口后立即释放端口号
# tcp_sever_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# 给程序绑定端口号
tcp_sever_socket.bind(('', 8080))
# 设置监听
tcp_sever_socket.listen(128)
# 等待客户端的建立连接请求
conn_socket, ip_port = tcp_sever_socket.accept()
# 接收客户端的ip地址和端口号
print(f'客户端的ip地址和端口号:{ip_port}')
# 接收客户端发送的数据
recv_data = conn_socket.recv(1024).decode('gbk')
print(f'接收用户的数据是:{recv_data}')
# 准备发送的数据
send_data = ('正在接收数据·····,问题正在处理中.....'.encode('gbk'))
conn_socket.send(send_data)
# 关闭套接字对象
conn_socket.close()
tcp_sever_socket.close()
3、tcp服务器多线程版本
import socket
import threading
def reply_request(conn_socket, ip_port):
# 10、循环处理客户端的请求
while True:
# 7、接收客户端的请求
recv_data = conn_socket.recv(1024)
if recv_data:
print(f'客户端的信息:{ip_port}')
print("客户端发送的数据:", recv_data.decode('gbk'))
# 8、返回数据给客户端
conn_socket.send('信息已收到!'.encode('gbk'))
else:
print(ip_port, '客户端已下线')
break
# 关闭套接字对象
conn_socket.close()
if __name__ == '__main__':
# 1、创建TCP服务端的套接字对象
tcp_sever_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设置端口复用
tcp_sever_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# 2、绑定IP和端口号
tcp_sever_socket.bind(('', 8080))
# 3、开始监听
tcp_sever_socket.listen(128)
while True:
# 4、等待客户端连接,产生新的套接字
conn_socket, ip_port = tcp_sever_socket.accept()
# 5、创建多线程
sub_thread = threading.Thread(target=reply_request, args=(conn_socket, ip_port))
# 设置守护主线程
sub_thread.setDaemon(True)
# 6、启动线程
sub_thread.start()
4、静态Web服务器之返回固定页面
import socket
# 创建套接字对象
tcp_sever_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设置端口复用
tcp_sever_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# 绑定端口号
tcp_sever_socket.bind(('', 9000))
# 开始监听
tcp_sever_socket.listen(128)
while True:
# 等待接收客户端的连接请求,并创建新的套接字
conn_socket, ip_port = tcp_sever_socket.accept()
# 接收客户端的http请求
recv_client_data = conn_socket.recv(4096)
# 对接收的http请求数据进行解码
recv_data_content = recv_client_data.decode('utf-8')
print('接收到客户端浏览器的http请求为:', recv_client_data)
# 读取文件数据
with open('Static_Sever/Nothing.png', 'rb') as file:
# with open('D:/Static_Sever/index01.html', 'rb') as file:
# with open('D:/Static_Sever/index.html', 'rb') as file:
file_data = file.read()
# 响应行
response_line = 'HTTP/1.1 200 OK\r\n'
# 响应头
response_header = 'Server:PWS1.0\r\n'
# response_header = 'Server:PWS1.0\r\nContent-type:text/html; charset=utf-8\r\n' # utf-8对于html中内容是通用的
# 响应体
response_body = file_data
# 拼接响应报文
response_data = (response_line + response_header + '\r\n').encode('utf-8') + response_body
# 发送http响应报文
conn_socket.send(response_data)
# 关闭套接字
conn_socket.close()
5、静态Web服务器之返回指定页面
while True:
# 等待接收客户端连接请求
conn_client_socket, ip_port = tcp_server_socket.accept()
# 接收HTTP请求报文
recv_client_data = conn_client_socket.recv(4096)
# 对接收数据进行转码
if len(recv_client_data) > 0:
recv_client_content = recv_client_data.decode('utf-8')
print(recv_client_content)
# 获取用户的请求资源路径
request_path = recv_client_content.split(' ', maxsplit=2)[1]
# 如果获取的请求路径没输入,默认为/
if request_path == '/':
request_path = '/index.html'
# 发送响应报文
with open('Static_Sever' + request_path, 'rb') as file:
file_data = file.read()
# 响应行
response_line = 'HTTP/1.1 200 OK\r\n'
# 响应头
response_header = 'Server:PWB1.0\r\n'
# 响应体
response_body = file_data
# 组装响应报文
response_data = (response_line + response_header + '\r\n').encode('utf-8') + response_body
# 发送响应报文
conn_client_socket.send(response_data)
# 关闭套接字对象
conn_client_socket.close()
6、静态Web服务器之返回指定页面(进阶版)
import socket
if __name__ == '__main__':
# 1、创建套接字对象
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2、绑定端口
tcp_server_socket.bind(('', 8080))
# 3、设置监听
tcp_server_socket.listen(128)
while True:
# 4、接收客户端连接请求
conn_socket, ip_port = tcp_server_socket.accept()
# 5、接收数据(HTTP请求报文)
recv_client_data = conn_socket.recv(4096)
if len(recv_client_data) > 0:
recv_client_content = recv_client_data.decode('utf-8')
# print(recv_client_content)
# 获取用户请求的资源路径(资源格式 => GET 请求资源路径 HTTP/1.1)
request_path = recv_client_content.split(' ', maxsplit=2)[1]
# print(request_path)
# 特殊情况:如果request_path == '/',则应该让其访问项目的首页!
if request_path == '/':
request_path = '/index.html'
# 6、发送数据(HTTP响应报文)
try:
with open('Static_Sever' + request_path, 'rb') as f: # 'static' + request_path = static/hlw.png
file_data = f.read()
except Exception as e:
# 如果文件不存在,则返回HTTP/1.1 404 Not Found
# ① 响应行
response_line = 'HTTP/1.1 404 Not Found\r\n'
# ② 响应头
response_header = 'Server:PWB1.0\r\n'
# ③ 响应体
with open('Static_Sever/error.html', 'rb') as f:
file_data = f.read()
response_body = file_data
# ④ 组装响应数据
response_data = (response_line + response_header + '\r\n').encode('utf-8') + response_body
conn_socket.send(response_data)
else:
# ① 响应行
response_line = 'HTTP/1.1 200 OK\r\n'
# ② 响应头
response_header = 'Server:PWB1.0\r\n'
# ③ 响应体
response_body = file_data
# ④ 组装响应数据
response_data = (response_line + response_header + '\r\n').encode('utf-8') + response_body
conn_socket.send(response_data)
finally:
# 7、关闭客户端与服务器端新产生套接字对象
conn_socket.close()
7、静态Web服务器之多任务版本(多线程)
import socket
import threading
def handle_client_request(conn_socket):
# 接收客户端发过来的HTTP请求
recv_client_data = conn_socket.recv(4096)
if len(recv_client_data) > 0:
# 数据解码
recv_client_content = recv_client_data.decode('utf-8')
# print(recv_client_content)
# 获取客户端资源请求路径
request_path = recv_client_content.split(' ', maxsplit=2)[1]
if request_path == '/':
request_path = '/index.html'
# 打开文件,获取客户端请求数据
try:
with open('Static_Sever' + request_path, 'rb') as f:
file_data = f.read()
except Exception as e:
# 找不到文件,返回404,Not Found
# 响应行
response_line = 'HTTP/1.1 404 Not Found\r\n'
# 响应头
response_header = 'Server:PWB1.0\r\n'
# 响应体
with open('Static_Sever/error.html', 'rb') as f:
file_data = f.read()
response_body = file_data
# 组装http响应报文
response_data = (response_line + response_header + '\r\n').encode('utf-8') + response_body
# 发送http响应报文
conn_socket.send(response_data)
else:
# 响应行
response_line = 'HTTP/1.1 200 OK\r\n'
# 响应头
response_header = 'Server:PWB1.0\r\n'
# 响应体
response_body = file_data
# 组装响应报文
response_data = (response_line + response_header + '\r\n').encode('utf-8') + response_body
# 发送响应报文
conn_socket.send(response_data)
finally:
conn_socket.close()
if __name__ == '__main__':
# 创建套接字对象
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 端口复用
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# 绑定端口号
tcp_server_socket.bind(('', 8080))
# 设置监听
tcp_server_socket.listen(128)
while True:
# 等待客户端的连接请求
conn_socket, ip_port = tcp_server_socket.accept()
# 创建子线程
sub_thread = threading.Thread(target=handle_client_request, args=(conn_socket,))
# 设置守护主线程
sub_thread.setDaemon(True)
sub_thread.start()
8、静态Web服务器之面向对象版本(类)
import socket
import threading
class HttpWebServer(object):
# 定义__init__方法,初始化套接字对象
def __init__(self):
# 创建套接字对象
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 端口复用
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# 绑定端口
tcp_server_socket.bind(('', 8080))
# 设置监听
tcp_server_socket.listen(128)
# 将tcp_server_socket设置为对象属性
self.tcp_server_socket = tcp_server_socket
@staticmethod
def handle_client_request(conn_socket):
# 接收客户端传送的请求数据
recv_client_data = conn_socket.recv(4096)
if len(recv_client_data) > 0:
# 将客户端请求数据转码
recv_client_content = recv_client_data.decode('utf-8')
print(recv_client_data)
# 获取客户端请求资源路径
request_path = recv_client_content.split(' ', maxsplit=2)[1]
if request_path == '/':
request_path = '/index.html'
# http响应报文
try:
with open('Static_Sever' + request_path, 'rb') as f:
file_data = f.read()
except Exception as e:
# 返回404 Not Found
# 响应行
response_line = 'HTTP/1.1 404 Not Found\r\n'
# 响应头
response_header = 'Server:PWB1.0\r\n'
# 响应体
with open('Static_Sever/error.html', 'rb') as f:
file_data = f.read()
response_body = file_data
# 组装响应报文
response_data = (response_line + response_header + '\r\n').encode('utf-8') + response_body
# 发送响应报文
conn_socket.send(response_data)
else:
# 响应行
response_line = 'HTTP/1.1 OK\r\n'
# 响应头
response_header = 'Server:PWB1.0\r\n'
# 响应体
response_body = file_data
# 组合响应报文
response_data = (response_line + response_header + '\r\n').encode('utf-8') + response_body
# 发送响应报文
conn_socket.send(response_data)
finally:
conn_socket.close()
def start(self):
while True:
# 接收客户端的HTTP连接请求
conn_socket, ip_port = self.tcp_server_socket.accept()
# 创建子进程
sub_thread = threading.Thread(target=self.handle_client_request, args=(conn_socket,))
# 设置守护主进程
sub_thread.setDaemon(True)
# 启动子进程
sub_thread.start()
if __name__ == '__main__':
# 创建类的对象
web_server = HttpWebServer()
# 启动Web程序
web_server.start()
|