【问题标题】:Python re-using same socket and getting problemsPython重新使用相同的套接字并遇到问题
【发布时间】:2011-07-10 18:40:40
【问题描述】:

我正在使用 Python 编写一个简单的脚本,该脚本将使用套接字连接到主机/端口。我知道套接字只能使用一次,这就是为什么我根本不关闭套接字,但是当我在端口 80 上连接到 localhost 并尝试像GET / 这样的简单命令时,它第一次工作但第二次执行@ 987654322@ 或任何其他 HTTP 命令,它不会打印输出。这是我所拥有的


import socket
size = 1024
host = 'localhost'
port = 80
def connectsocket(userHost, userPort):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #TCP socket
    s.connect((userHost, userPort))
    while(1):
        input = raw_input("Command: ")
        s.send(input + '\r\n\r\n') #Send command
        r = s.recv(size) #Recieve output
        print(r)
connectsocket(host, port)

我认为这会起作用,但这是一个示例输出:


amartin@homebox:~$ python socketconn.py
Command: GET /
[BUNCH OF HTML CODE]
Command: GET /

Command:

如您所见,它适用于第一个GET /,但不适用于第二个。我怎样才能解决这个问题?

【问题讨论】:

  • 您从哪里得知套接字只能使用一个?您可以重复使用套接字。
  • 我的意思是,如果你关闭一个套接字,你就不能使用同一个套接字。

标签: python http sockets tcp


【解决方案1】:

鉴于来自 cmets 的关于 @samplebias 答案的信息,我认为这与您想要完成的任务类似:

import errno
import socket

size = 1024
host = 'localhost'
port = 80


def connectsocket(userHost, userPort):

    while(1):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # TCP socket
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.connect((userHost, userPort))

        command = raw_input("Command: ")

        s.send(command + '\r\n\r\n')  # Send command
        response = s.recv(size)  # Recieve output
        print response

        try:
            s.shutdown(socket.SHUT_RDWR)
        except socket.error, exc:
            # Depending on the platform, shutting down one half of the
            # connection can also close the opposite half
            if exc.errno != errno.ENOTCONN:
                raise

        s.close()


connectsocket(host, port)

您也可以查看Twisted 库。你也可以看看这本书:Foundations of Python Network Programming。

python 文档网站上还有一个很好的 socket tutorial 可以提供帮助。最后但同样重要的是,我在 Google 上找到了一个 slightly more comprehensive tutorial,它看起来非常适合初学者。

HTH。

【讨论】:

  • 感谢您提供的所有信息,我将查看这些链接。另外,这段代码不会继续用循环打开一个新的套接字吗?这不会给你一个Tranport endpoint is already connected 错误吗?
  • 不,因为您已经关闭了端口并在最后关闭了它。一旦shutdown()/close()方法被执行,socket就不再连接了。
  • 我明白了。 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 是否需要在 while 循环中?
【解决方案2】:

您需要告诉服务器保持 TCP 连接打开并期待更多请求:

headers = 'Connection: keep-alive\r\n'
s.send(input + '\r\n' + headers + '\r\n')

另外,请尝试指定 HTTP 版本:

python socketconn.py 
Command: GET / HTTP/1.1

【讨论】:

  • 这是否适用于所有服务?不仅仅是http?编辑:刚刚尝试过,它似乎不起作用。我试过玩标题,但没有运气。
  • 以上是特定于 HTTP 的。例如,如果你想打开一个到 FTP 服务器的套接字,协议就完全不同了。您是在学习还是在尝试实现某种工具?如果是后者,您将需要使用现有库来为您处理 HTTP 协议和套接字通信,因为细节可能非常棘手。 urllib2 模块就是一个例子。
  • 好吧,我正在编写一个简单的工具。而且我希望它是通用的,因此它几乎可以与您连接的任何端口一起使用。
  • 如果你想构建一个通用的套接字轮询器,让你使用面向行的协议与套接字进行交互,这听起来是可行的。有点像带有更高级别命令集的 telnet。
  • 如果是这种情况,那么您需要重新提出您的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-19
  • 2023-04-03
  • 2021-02-04
  • 1970-01-01
  • 1970-01-01
  • 2015-08-17
  • 1970-01-01
相关资源
最近更新 更多