【问题标题】:Basic Python TCP Socket Server & Client基本 Python TCP 套接字服务器和客户端
【发布时间】:2018-07-02 14:01:02
【问题描述】:

我在这里的第一个问题,请温柔 :) 我正在尝试设置一个基本的 Python (2.7) TCP 套接字服务器,它是多线程的(我还没有进入多线程部分)和一个客户端。

这里是服务器:

# Basic TCP socket server

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

host = ''
port = 8888

s.bind((host, port))
s.listen(5)

while True:
    c, addr = s.accept()
    print("Connected to %s" % addr)
    c.send("Hello socket")
    c.close()    

这里是客户端:

# Basic TCP socket client

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

host = '127.0.0.1'
port = 8888

s.connect((host, port))
print s.recv(1024)

s.close()

当我运行服务器时,它似乎执行没有错误,但是当我运行客户端进行连接时,我没有看到应该打印到运行服务器的终端窗口的消息。这是错误(正如@Rawing 指出的那样):

Traceback(最近一次调用最后一次):文件“server.py”,第 19 行,在 print("Connected to %s" % addr) TypeError: 字符串格式化期间并非所有参数都转换

至于使服务器多线程,我需要阅读它,但欢迎提出任何建议。

谢谢。

【问题讨论】:

  • RE 多线程服务器:阅读 ZeroMQ。这是一种使套接字编程更加人性化的尝试。对于只想学习的人来说,它已经过时并且可能过于复杂,但是:文档非常棒,并解释了您在 python 中使用普通套接字编程时可能陷入的陷阱,以及如何在理论上和 ZeroMQ 中克服它们。
  • 在我的机器上运行良好 - 如果您希望打印的消息是 TypeError: not all arguments converted during string formatting
  • 第一件事让我大吃一惊的是c.close完全没有 - 你必须写c.close() 才能真正调用该方法。
  • 正如上述评论者所说,这确实尝试进行打印然后摔倒。有没有可能你正在做一些奇怪的事情。建立连接时防止服务器的标准输出正确刷新的终端设置?
  • 请将运行这些程序时看到的实际输出复制粘贴到您的问题中。

标签: python python-2.7 sockets


【解决方案1】:

bind服务器到一个ip,例如:host='127.0.0.1,它应该可以工作。

更新:我完全错了。我在您的脚本中修复了一些问题并假设这是问题所在,但事实并非如此 - 正如下面的回复所述,绑定到 ('', ) 是完全有效的。

看起来您的套接字代码非常好,但落在了 print 语句上。我用print("Connected to {}".format(addr))修复了它

【讨论】:

  • 绑定到'' 是完全有效的。它是INADDR_ANY 的简写。例如,参见this example
【解决方案2】:

您的代码中有两个问题

  • 您在服务器程序中使用的字符串格式化运算符% 不正确。如果您将一个元组传递给%(并且addr 是一个元组),那么元组中的每个项目都必须匹配一个格式化指令。这就是您的服务器程序失败的原因。

    print("Connected to %s" % str(addr))
    
  • 在这两个程序中,您提到但不调用 socket.close。在适当的位置尝试这些:

    s.close()
    c.close()
    

【讨论】:

  • 注意:OP 编辑​​了问题以在socket.close 行中添加括号。在原始问题中,这些行看起来像 s.closec.close
  • 我应该用代码更新编辑我的原始帖子还是用代码更新做一个新的回复?我以为我已经阅读了更新原始评论的指南。
  • 我修复了socket.close 的语法,因此它们被调用,并使用了您的打印功能......现在它可以工作了。
【解决方案3】:

python 3 中 TCP 服务器的简单实现(如果你愿意使用它而不是 2.7)

服务器:

import socketserver

class MyTCPHandler(socketserver.BaseRequestHandler):
    def handle(self):
        data = self.rfile.readline() # Receive data from client
        self.wfile.write(new_data) # Send data to client


if __name__ == "__main__":
    with socketserver.UDPServer((HOST, PORT), MyUDPHandler) as server:
        server.serve_forever()

客户:

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
    sock.connect((HOST, PORT)) # Connect
    sock.sendall(bytes(data + "\n", "utf-8")) # Send data
    received = str(sock.recv(1024), "utf-8") # Receive data synchronically

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-11
    • 1970-01-01
    • 1970-01-01
    • 2019-01-31
    • 2012-11-15
    • 2017-07-10
    • 2013-10-24
    • 1970-01-01
    相关资源
    最近更新 更多