You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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识别。

  • 两种修正方案

    1. 改用标准URL格式传参
      把命令改成python web_client.py http://localhost:8080/index.html GET,这样urlparse能正确拆分出netloc=localhost:8080和path=/index.html。
    2. 修改客户端解析逻辑适配原格式
      如果不想改命令格式,手动拆分参数:
      # 在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
      
  • 额外小问题修复

    • 客户端中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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 21:31:11