我启动并运行了UDP通信。 在一个简单的条带化版本中,客户端基本上是这样做的:(是的,代码中有很多ifs和错误检查,不,没有很多定义,它将无法正常工作。但我更多的是在概念上这里比实际代码)
sock = socket(AF_INET, SOCK_DGRAM, 0);
server_length = sizeof(struct sockaddr_in);
sendto(sock, "Hi", 3, 0, (struct sockaddr *)&myaddr, server_length);
numRes = recvfrom(sock, (char *)buff, (int)sizeof(buff), 0, (struct sockaddr *)&myaddr, &server_length);
服务器基本相同:
sock=socket(AF_INET, SOCK_DGRAM, 0);
bind(sock,(struct sockaddr *)&server,length);
resBytes=recvfrom(sock,buff,(int)sizeof(buff),0,(struct sockaddr *)&from, &fromlen);
sendto(sock, "Test",5, 0, (struct sockaddr *)&from, fromlen);
这很有效。两端都接收到另一端发送的数据。
这是我的问题:服务器应该同时处理大量请求。我为这些消息创建了一个队列,以便另一个线程可以处理它们,然后再将它们发送回另一个线程中的客户端。当我这样做时,我为发送创建了一个新的套接字,使用相同的"来自"消息后面的地址,但客户端永远不会收到它。
理解回复UDP消息必须使用相同的套接字是否正确?
如果我使用相同的套接字进行发送和接收,如果我有三个客户端发送消息会发生什么,然后在处理完这些消息后,我会以随机顺序回答它们。这有用吗?
我可以制作一台服务器"在客户端,但我的猜测是任何NAT都会快速杀死这个想法。
我尝试尝试的或多或少是这样的:
sock=socket(AF_INET, SOCK_DGRAM, 0);
sock2=socket(AF_INET, SOCK_DGRAM, 0);
bind(sock,(struct sockaddr *)&server,length);
resBytes=recvfrom(sock,buff,(int)sizeof(buff),0,(struct sockaddr *)&from, &fromlen);
sendto(sock2, "Test",5, 0, (struct sockaddr *)&from, fromlen);
如果这种代码可行,我会回到我的调试,但现在看来情况并非如此。
编辑: 有人补充说"多线程"作为标签。忘掉多线程的东西它更能解释为什么我不会对同一个请求做出反应。如果需要,我可以在一个线程中进行所有通信。很抱歉,如果这让人感到困惑,但我的主要问题是:a)我可以在没有定义"服务器的情况下向另一个人发送响应吗?在客户端上。 b)如果没有,它将如何在同一个socked上处理随机的回复顺序(IE客户端A发送,客户端B发送,回答客户端B,然后回复客户端A)
答案 0 :(得分:1)
只要没有连接套接字,单个UDP套接字就可以从多个源接收数据并将数据发送到多个对等体。这意味着如果您显式或隐式绑定套接字然后使用sendto
和recvfrom
(或recv
),那么您可以使用相同的套接字来发送和接收来自多个对等方的数据。但是,如果您首先connect
套接字,那么您将只能从绑定到连接的ip:端口的套接字接收数据,即通常是接收数据的同一套接字。
要测试这个,你可以使用一个简单的Python服务器(与C一样工作)。此服务器创建两个套接字:sock1
和sock2
。它将在sock1
上收到一条消息,然后使用第一个sock2
(未收到原始消息的消息)发送消息,然后sock1
(收到原始消息的消息) ):
from socket import *
sock1 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
sock2 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
sock1.bind(('127.0.0.1',9999))
data,addr = sock1.recvfrom(1024)
print("got '{}' from {}".format(data,addr))
sock2.sendto(b"send from sock2", addr)
sock1.sendto(b"send from sock1", addr)
作为对等体,我们有一个客户端,根据配置使用连接的套接字(即connect
+ send
)或未连接的套接字(即没有connect
和{{1} }):
sendto
如果您使用已连接的套接字(from socket import *
connected=False
sock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP)
if connected:
sock.connect(('127.0.0.1',9999))
sock.send('send from connected client')
else:
sock.sendto('send from unconnected client',('127.0.0.1',9999))
while True:
data,addr = sock.recvfrom(1024)
print("got '{}' from {}".format(data,addr))
)运行客户端,您将看到它只会从connected=True
收到消息,因为sock1
已明确绑定到客户端连接的ip:端口,sock1
(隐式)绑定到其他地址:
sock2
如果客户端使用未连接的套接字(got 'send from sock1' from ('127.0.0.1', 9999)
),则会收到来自connected=False
和sock1
的消息:
sock2