Python HTTP/1.1客户端连接失败:socket.gaierror错误求助
问题描述
我是Python新手,正在修计算机网络课程,连续两天花数小时排查问题:运行支持GET/HEAD请求的HTTP客户端(命令格式python web_client.py host:port/path [METHOD])时,GET请求始终报错,错误出在socket连接步骤。
server.py 代码
from socket import * import socket serverSocket = socket.socket(AF_INET, SOCK_STREAM) serverSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) #resets if there is a problem serverPort=8080 serverSocket.bind(('',serverPort)) serverSocket.listen(1) print("Server is Ready") while True: try: connectionSocket, addr = serverSocket.accept() print(addr) message = connectionSocket.recv(1024) message.decode() print('Msg is: ') #Path is second part of HTTP header denoted by [1] filename = message.split()[1] print('File name is: ', filename) f = open(filename[1:]) #Store the entire contenet of the requested file in a temporary buffer outputdata = f.read() # Send the HTTP response header line to the connection socket connectionSocket.send("HTTP/1.1 200 OK\r\n\r\n") # Send the content of the requested file to the connection socket for i in range(0, len(outputdata)): connectionSocket.send(outputdata[i].encode()) connectionSocket.send("\r\n") # Close the client connection socket connectionSocket.close() except IOError: connectionSocket.send("HTTP/1.1 404 Not Found\r\n\r\n") connectionSocket.close() serverSocket.close()
client.py 代码
import socket from urllib.parse import urlparse import re import os import sys socket.setdefaulttimeout = 0.50 os.environ['no_proxy'] = '127.0.0.1,localhost' linkRegex = re.compile('<a\s*href=[\'|"](.*?)[\'"]*?>') CRLF = "\r\n\r\n" def GET(url): print("Get method") url = urlparse(url) path = url.path print("path", path) print("url", url) if path == "": path = "/" HOST = url.netloc # The remote host PORT = 8080 # The same port as used by the server # create an INET, STREAMing socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) print("HOST", HOST) print("PORT",PORT) print("s", s) s.settimeout(0.30) s.setsockopt(socket.SOL_SOCKET, SO_REUSEADDR, 1) # set up TCP connection - THIS IS WHERE THE ERROR IS!!!!!! s.connect((HOST, PORT)) print("Got here msg", (path, CRLF))#NOT SHOWING UP BECAUSENOT GETTING TO THIS STEP! msg = "GET%s HTTP/1.1%s" % (path, CRLF) print("msg request:\n", msg) # send HTTP get request s.send(msg.encode()) dataAppend = '' # wait for response from server data = (s.recv(10000000)) if not data: print('error, no response') else: dataAppend = dataAppend, repr(data) # shutdown and close tcp connection and socket s.shutdown(1) s.close() print('Received', dataAppend) def HEAD(url): print('Head method') if sys.argv[2] == "GET": GET(sys.argv[1]) elif sys.argv[2] == "HEAD": HEAD(sys.argv[1])
错误信息
socket.gaierror: [Errno 11011] getaddrinfo failed
问题原因与解决办法
这个gaierror是DNS解析失败导致的,核心问题出在命令行参数格式和客户端的URL解析逻辑不匹配:
命令行参数格式问题
你使用的host:port/path格式无法被urlparse正确解析,它会把整个字符串当成主机地址(netloc),导致HOST变量包含路径部分,无法被DNS识别。两种修正方案
- 改用标准URL格式传参
把命令改成python web_client.py http://localhost:8080/index.html GET,这样urlparse能正确拆分出netloc=localhost:8080和path=/index.html。 - 修改客户端解析逻辑适配原格式
如果不想改命令格式,手动拆分参数:
或者直接拆分主机、端口和路径:# 在GET函数开头替换原urlparse逻辑 url_str = sys.argv[1] # 补全协议头让urlparse能正确解析 if '://' not in url_str: url_str = 'http://' + url_str url = urlparse(url_str)# 替代urlparse的代码 host_path = sys.argv[1].split('/', 1) host_port = host_path[0] path = '/' + host_path[1] if len(host_path) > 1 else '/' # 拆分主机和端口 if ':' in host_port: HOST, PORT = host_port.split(':', 1) PORT = int(PORT) else: HOST = host_port PORT = 8080
- 改用标准URL格式传参
额外小问题修复
- 客户端中
socket.setdefaulttimeout = 0.50是错误写法,应该改为函数调用:socket.setdefaulttimeout(0.50)。 - 服务器中
message.decode()没有保存结果,需改为message = message.decode(),否则后续split()操作的是字节串,可能引发错误。 - 服务器发送响应时,要使用字节串格式:
connectionSocket.send(b"HTTP/1.1 200 OK\r\n\r\n"),避免编码异常。
- 客户端中
内容的提问来源于stack exchange,提问作者user15928679
相关产品推荐
相关产品推荐

