UDP和套接字响应客户端

时间:2017-12-09 12:11:45

标签: multithreading sockets networking udp

我启动并运行了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)

1 个答案:

答案 0 :(得分:1)

只要没有连接套接字,单个UDP套接字就可以从多个源接收数据并将数据发送到多个对等体。这意味着如果您显式或隐式绑定套接字然后使用sendtorecvfrom(或recv),那么您可以使用相同的套接字来发送和接收来自多个对等方的数据。但是,如果您首先connect套接字,那么您将只能从绑定到连接的ip:端口的套接字接收数据,即通常是接收数据的同一套接字。

要测试这个,你可以使用一个简单的Python服务器(与C一样工作)。此服务器创建两个套接字:sock1sock2。它将在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=Falsesock1的消息:

sock2