由于我在学习时,在网络上找到了大量解释http协议的文章,以及下列的服务端客户端代码,但很少有文章对这两段代码进行解释,所以在此记录我个人的理解,如有错误,还请在评论区纠正。
功能
写一个代码。分客户端和服务器端。客户端发送一个http请求给服务器,服务器响应 “hello world”给客户端。服务器接收到请求时,要打印出客户端ip,并输出到一个文本a.txt。
服务端(server.py)
import socket
def handle_client_request(client_socket, client_address)://接收到请求后对其进行处理
request = client_socket.recv(1024).decode()
print(f"Received request from client IP: {client_address[0]}")
//输出客户端ip
response = "Hello World"
client_socket.send(response.encode())
//接收到请求后向客户端发起响应
with open("a.txt", "w") as f:
f.write(f"Client IP: {client_address[0]}\n")
//将客户端的ip写入a.txt
client_socket.close()
def run_server():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("172.19.0.2", 22))
//注意这里就是双括号,否则会报错TypeError: bind() takes exactly one argument (2 given)
server_socket.listen(1)
//等待接收请求
print("Server started. Listening for incoming connections...")
while True:
client_socket, client_address = server_socket.accept()
handle_client_request(client_socket, client_address)
run_server()
在上述代码中, server_socket.bind()用于绑定服务端的ip地址与端口(服务端是运行server.py的机器),一般情况下可以是机器的ip地址,也可以用127.0.0.1或localhost来代替,但在dockerfile构建的docker镜像中只能使用容器的ip。
客户端(client.py)
import socket
def run_client():
server_address = ("172.19.0.2", 22)
//确定客户端请求的对象————服务端的ip和端口
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(server_address)
//连接服务端
request = "GET / HTTP"
client_socket.send(request.encode())
//向服务端发起get请求
response = client_socket.recv(1024).decode()
print(f"Server response: {response}")
//接受服务端的响应并输出响应内容
client_socket.close()
run_client()
上述代码中server_address绑定服务端ip与端口,决定了客户端给谁发消息,然后有一个请求(request = "GET / HTTP/1.1")即可,像request = "GET / HTTP/1.1\r\nHost: 139.9.223.163:5010\r\n\r\n"这样的get请求中的ip实际没有意义,get请求的作用是向服务端发起请求,客户端的ip由服务端自行捕获。