Python UDP客户端/服务器程序问题

10
我正在尝试编写一个基本的客户端/服务器回显程序,用于测试基于select()的重传定时器的使用(尽管我不得不注释掉那一部分以简化调试,因为它没有按照预期工作)。以下是相关代码片段:
服务器:
from socket import *
import sys
import select
address = ('localhost', 6005)
server_socket = socket(AF_INET, SOCK_DGRAM)
server_socket.bind(address)

while(1):
    print "Listening"
    recv_data, addr = server_socket.recvfrom(2048)
    print recv_data
    if recv_data == "Request 1" :
        print "Received request 1"
        server_socket.sendto("Response 1", address)
    elif recv_data == "Request 2" :
        print "Received request 2"
        data = "Response 2"
        server_socket.sendto(data, address)

客户端:

from socket import *
import sys
import select

address = ('localhost', 6005)
client_socket = socket(AF_INET, SOCK_DGRAM)

num_retransmits = 0
while(num_retransmits < 60):
    num_retransmits = num_retransmits + 1


    data = "Request 1"
    client_socket.sendto(data, address)
    print "Sending request 1"

    recv_data, addr = client_socket.recvfrom(2048)

    print recv_data, "!!"

客户端的输出仅为“Sending request 1”,当在recvfrom调用以下的任何位置设置断点时,它都不会到达断点。因此,我认为客户端没有收到任何东西,并一直等待直到收到消息。另一方面,服务器上的输出是:

  • Listening
  • Request 1
  • Received request 1
  • Listening
  • Response 1

之后再次循环,服务器循环并打印RESPONSE 1。这意味着服务器所做的是接收请求1,将响应1发送给客户端,然后循环...但在它第二次循环后,响应1仍然保存在其套接字中!这就是为什么当它打印recv_data时,它会打印响应1。另一方面,客户端没有打印recv_data,因为客户端还没有收到它 - 它仍然在服务器套接字的缓冲区中。

请帮忙看看 - 我已经尝试查看其他回显程序,但它们似乎都使用TCP并且非常简单(我认为我已经遵循了相同的步骤)。我不知道为什么我的UDP程序无法工作。我尝试查看sendall()调用,但它似乎只适用于TCP。

3个回答

14

你需要发送至 addr 而不是 address。

from socket import *
import sys
import select
address = ('localhost', 6005)
server_socket = socket(AF_INET, SOCK_DGRAM)
server_socket.bind(address)

while(1):
    print "Listening"
    recv_data, addr = server_socket.recvfrom(2048)
    print recv_data
    if recv_data == "Request 1" :
        print "Received request 1"
        server_socket.sendto("Response 1", addr)
    elif recv_data == "Request 2" :
        print "Received request 2"
        data = "Response 2"
        server_socket.sendto(data, addr)

谢谢!由于某些原因,这篇帖子没有显示出来:S 但是,是的,那解决了。 - misaochan

2
这里发生的情况是服务器向localhost:6005发送'Response 1',并立即接收它,因为它也在监听localhost:6005
服务器绑定并侦听其(地址、端口),这是正确的。当客户端连接而不先绑定时,它会自动分配一个未使用的(地址、端口)。你需要确定客户端正在使用哪个(地址、端口),以便对其进行响应——可以通过bind显式设置已知的(地址、端口),或者使用recvfrom返回的addr

谢谢,我也是这么想的。不过,这肯定是在同一台机器上测试服务器和客户端的唯一方法 - 将服务器绑定到端口A和“localhost”,然后使用客户端将内容发送到端口A和localhost。bind()函数是否也适用于客户端? - misaochan
哦,谢谢!现在一切都修好了。由于某种原因,我误以为服务器和客户端都必须在本地使用相同的端口... - misaochan
@JosephineLim Bind可以用于客户端套接字,但这很少见。 - ephemient

1

可能是服务器端的第10行

recv_data,addr = server_socket.recvfrom(2048)

应该改为

recv_data,addr = server_socket.sendto(2048)

?

ps> 我是个新手。=P


4
谢谢。尝试回答您的问题让我学到了更多,比起我能从您那里得到的任何东西都更有收获。 - H_7

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接