C++ 同时接收 2 条或更多 UDP 消息
C++ Receiving 2 or more UDP Messages at same time
我正在尝试在我的main.cxx中接收UDP消息。我创建了一个UDP服务器方法getUdp(char *buffer)来监听while(true)无限循环中的传入UDP消息。
这是我面临的问题。此 UDP 服务器能够一次侦听一条消息。当两个或多个 UDP 消息同时出现时,它不会排队进入缓冲区。我想这是因为每次在无限循环中调用该方法时,getUdp() 方法都会打开一个套接字,获取消息并关闭套接字,导致服务器无法对消息进行排队。
如何调整此代码以接收 2 条或更多 UDP 消息?感谢任何建议。
谢谢。
UdpServer.cpp
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <winsock.h>
#include <time.h>
#include "UdpServer.h"
#include "stdafx.h"
using namespace std;
#pragma comment(lib, "ws2_32.lib")
#define BUFFER_SIZE 4096
void getUDP(char *buffer);
void UDPServer::MyUDP::getUDP(char *buffer)
{
WSADATA w; /* Used to open windows connection */
int client_length; /* Length of client struct */
int bytes_received; /* Bytes received from client */
SOCKET sd; /* Socket descriptor of server */
struct sockaddr_in server; /* Information about the server */
struct sockaddr_in client; /* Information about the client */
struct hostent *hp; /* Information about this computer */
char host_name[256]; /* Name of the server */
time_t current_time; /* Current time */
/* Open windows connection */
if (WSAStartup(0x0101, &w) != 0)
{
fprintf(stderr, "Could not open Windows connection.n");
}
/* Open a datagram socket */
sd = socket(AF_INET, SOCK_DGRAM, 0);
if (sd == INVALID_SOCKET)
{
fprintf(stderr, "Could not create socket.n");
WSACleanup();
}
/* Clear out server struct */
memset((void *)&server, ' ', sizeof(struct sockaddr_in));
/* Set family and port */
server.sin_family = AF_INET;
server.sin_port = htons(11000);
/* Set address automatically if desired */
/* Get host name of this computer */
gethostname(host_name, sizeof(host_name));
hp = gethostbyname(host_name);
/* Check for NULL pointer */
if (hp == NULL)
{
fprintf(stderr, "Could not get host name.n");
closesocket(sd);
WSACleanup();
}
unsigned int a = 127;
unsigned int b = 0;
unsigned int c = 0;
unsigned int d = 1;
/* Assign the address */
server.sin_addr.S_un.S_un_b.s_b1 = a;
server.sin_addr.S_un.S_un_b.s_b2 = b;
server.sin_addr.S_un.S_un_b.s_b3 = c;
server.sin_addr.S_un.S_un_b.s_b4 = d;
/* Bind address to socket */
if (bind(sd, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) == -1)
{
fprintf(stderr, "Could not bind name to socket.n");
closesocket(sd);
WSACleanup();
}
/* Print out server information */
printf("Server running on %u.%u.%u.%un", (unsigned char)server.sin_addr.S_un.S_un_b.s_b1,
(unsigned char)server.sin_addr.S_un.S_un_b.s_b2,
(unsigned char)server.sin_addr.S_un.S_un_b.s_b3,
(unsigned char)server.sin_addr.S_un.S_un_b.s_b4);
printf("Press CTRL + C to quitn");
/* Loop and get data from clients */
client_length = (int)sizeof(struct sockaddr_in);
/* Receive bytes from client */
bytes_received = recvfrom(sd, buffer, BUFFER_SIZE, 0, (struct sockaddr *)&client, &client_length);
if (bytes_received < 0)
{
fprintf(stderr, "Could not receive datagram.n");
closesocket(sd);
WSACleanup();
}
current_time = time(NULL);
closesocket(sd);
WSACleanup();
}
主.cxx
int main(int argc, char** argv)
{
while(true)
{
//! wait for UDP message
UDPServer::MyUDP myudp;
myudp.getUDP(buffer);
if(buffer[0] != 0)
{
string udpMsg(buffer);
if(udpMsg == "ProcessThisMessage")
{
memset(&buffer[0], 0, sizeof(buffer));
cout << "UDP Message: " + udpMsg;
}
...
}
}
}
我想这是因为每次调用该方法时都会使用套接字 在无限循环中,getUdp() 方法打开一个套接字,获取 消息并关闭套接字,导致服务器无法 以对消息进行排队。
你的直觉是正确的。 当您将 UDP 套接字绑定到端口时,网络堆栈将为您缓冲(有限数量的)传入 UDP 数据包,以便(假设您相对及时地调用 recv(),不会丢失任何传入数据包。 但是当你关闭套接字()时,该缓冲区被释放,当然,在没有套接字绑定到UDP端口并且收到UDP数据包的时候,传入的UDP数据包将被丢弃(即根本不缓冲),因为没有套接字绑定到该端口。
如何调整此代码以接收 2 条或更多 UDP 消息? 感谢任何建议。
至少从概念上讲,您需要将getUdp()方法拆分为三个独立的部分:Setup()部分,您可以在程序启动时调用一次,Receive()部分(仅包含recv()调用),您可以根据需要多次调用以接收下一个数据包,最后是Cleanup()部分,用于关闭套接字并关闭TCP堆栈(仅在程序大约退出)。 这样,UDP 套接字在程序运行的整个过程中保持有效并绑定到端口,以便操作系统将可靠地缓冲传入的 UDP 数据包,以通过 recv() 提供给程序。
- 如何在C++中创建特定大小的消息以通过UDP套接字发送?
- C++ UDP 服务器在获取客户端地址配置时发送消息
- UDP 客户端不会在 esp32 上广播消息
- C# UDP 套接字无法接收消息
- 来自 C++ 的 UDP 消息不会被 Rust 接收
- 从 ICMP 消息访问 UDP
- 打包用于 UDP 网络的消息
- UDP测试代码未接收消息(C++)
- 如何将 UDP 消息发送到局域网中的每台计算机
- C++ 同时接收 2 条或更多 UDP 消息
- 即使在客户端停止或服务器重新启动后,UDP 消息仍会不断到达
- 将多个 UDP 消息发送到单个修订者
- 将结构转换为要传递给 UDP 的常规消息格式
- 在一条UDP消息中发送两个数据块,而不复制数据块
- UDP套接字是否将接收到的数据划分为不同的消息,或者recv是否同时读取尽可能多的数据
- libcurl是否能够通过UDP发送http消息
- 使用boost的多种数据类型的Udp消息
- 服务器端口没有接收到UDP消息
- 简单UDP套接字代码,发送和接收消息
- Linux-app无法从169.254.x获取UDP消息.X(本地链路)