C++ 获取传入UDP数据包的目标端口
我已经阅读了ip手册页和套接字手册页,我所能找到的只是标题中C++ 获取传入UDP数据包的目标端口,c++,linux,sockets,c++11,udp,C++,Linux,Sockets,C++11,Udp,我已经阅读了ip手册页和套接字手册页,我所能找到的只是标题中ip\u PKTINFO控制消息中的目标ip地址,似乎无法从数据包的标题中提取目标端口。还是有 如果没有,是否有办法从数据包到达的套接字获取端口?当您使用普通套接字时,可以在套接字fd上使用recvfrom。recvfrom的手册页: RECV(2) 名字 recv, recvfrom, recvmsg - receive a message from a socket 概要 recvfrom() recvfrom()将收到的消
ip\u PKTINFO
控制消息中的目标ip地址,似乎无法从数据包的标题中提取目标端口。还是有
如果没有,是否有办法从数据包到达的套接字获取端口?当您使用普通套接字时,可以在套接字fd上使用recvfrom。recvfrom的手册页: RECV(2) 名字
recv, recvfrom, recvmsg - receive a message from a socket
概要
recvfrom()
recvfrom()将收到的消息放入缓冲区buf。调用方必须指定
在len中的缓冲区
If src_addr is not NULL, and the underlying protocol provides the source address of the message,
that source address is placed in the buffer pointed to by src_addr. In this case, addrlen is a
value-result argument. Before the call, it should be initialized to the size of the buffer
associated with src_addr. Upon return, addrlen is updated to contain the actual size of the
source address. The returned address is truncated if the buffer provided is too small; in this
case, addrlen will return a value greater than was supplied to the call.
If the caller is not interested in the source address, src_addr and addrlen should be specified
as NULL.
beej指南中的一个示例:
// datagram sockets and recvfrom()
struct addrinfo hints, *res;
int sockfd;
int byte_count;
socklen_t fromlen;
struct sockaddr_storage addr;
char buf[512];
char ipstr[INET6_ADDRSTRLEN];
// get host info, make socket, bind it to port 4950
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;
getaddrinfo(NULL, "4950", &hints, &res);
sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
bind(sockfd, res->ai_addr, res->ai_addrlen);
// no need to accept(), just recvfrom():
fromlen = sizeof addr;
byte_count = recvfrom(sockfd, buf, sizeof buf, 0, &addr, &fromlen);
printf("recv()'d %d bytes of data in buf\n", byte_count);
printf("from IP address %s\n",
inet_ntop(addr.ss_family,
addr.ss_family == AF_INET?
((struct sockadd_in *)&addr)->sin_addr:
((struct sockadd_in6 *)&addr)->sin6_addr,
ipstr, sizeof ipstr);
,
希望这对您有所帮助因为您使用的是普通套接字,所以可以在套接字fd上使用recvfrom。recvfrom的手册页: RECV(2) 名字
recv, recvfrom, recvmsg - receive a message from a socket
概要
recvfrom()
recvfrom()将收到的消息放入缓冲区buf。调用方必须指定
在len中的缓冲区
If src_addr is not NULL, and the underlying protocol provides the source address of the message,
that source address is placed in the buffer pointed to by src_addr. In this case, addrlen is a
value-result argument. Before the call, it should be initialized to the size of the buffer
associated with src_addr. Upon return, addrlen is updated to contain the actual size of the
source address. The returned address is truncated if the buffer provided is too small; in this
case, addrlen will return a value greater than was supplied to the call.
If the caller is not interested in the source address, src_addr and addrlen should be specified
as NULL.
beej指南中的一个示例:
// datagram sockets and recvfrom()
struct addrinfo hints, *res;
int sockfd;
int byte_count;
socklen_t fromlen;
struct sockaddr_storage addr;
char buf[512];
char ipstr[INET6_ADDRSTRLEN];
// get host info, make socket, bind it to port 4950
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;
getaddrinfo(NULL, "4950", &hints, &res);
sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
bind(sockfd, res->ai_addr, res->ai_addrlen);
// no need to accept(), just recvfrom():
fromlen = sizeof addr;
byte_count = recvfrom(sockfd, buf, sizeof buf, 0, &addr, &fromlen);
printf("recv()'d %d bytes of data in buf\n", byte_count);
printf("from IP address %s\n",
inet_ntop(addr.ss_family,
addr.ss_family == AF_INET?
((struct sockadd_in *)&addr)->sin_addr:
((struct sockadd_in6 *)&addr)->sin6_addr,
ipstr, sizeof ipstr);
,
希望这有帮助您是在谈论原始插座吗?普通UDP套接字绑定到地址和端口。不,不是原始套接字,是,它绑定到多个端口的线程池内的ip/端口。还使用boost.I使用boost_socket.native()访问头文件等。您是在说原始套接字吗?普通UDP套接字绑定到地址和端口。不,不是原始套接字,是,它绑定到多个端口的线程池内的ip/端口。还使用boost.I使用boost_socket.native()访问标题等。感谢您的输入。我已经出于多种原因使用了
recvfrom
和recvmsg
。但是,sockadd\u-in
结构的sin\u-addr
和sin\u-port
保存源IP和端口,而不是目标。无论如何,我通过使用boost::asio::socket\u base::reuse\u address选项(true)解决了我的问题
设置SO\u重用
标志,允许多个套接字使用同一端口。然而,我仍然不明白为什么在传入的数据包上不容易访问目标端口。。。它一定在某个地方。当您创建一个普通套接字时,您应该在绑定该套接字时指定端口和ip,这样您就知道消息到达的端口(因为您在绑定套接字时设置了该端口)。你能更详细地解释一下你的情况吗?这是真的,但我们可以对目标IP说同样的话,它可以在msghdr
中找到。我们的threadpool设计意味着我们可能会面临无法将端口与其对应的传入数据包正确匹配的风险,读取数据包头将是一种更安全的方法。感谢您的输入。我已经出于多种原因使用了recvfrom
和recvmsg
。但是,sockadd\u-in
结构的sin\u-addr
和sin\u-port
保存源IP和端口,而不是目标。无论如何,我通过使用boost::asio::socket\u base::reuse\u address选项(true)解决了我的问题
设置SO\u重用
标志,允许多个套接字使用同一端口。然而,我仍然不明白为什么在传入的数据包上不容易访问目标端口。。。它一定在某个地方。当您创建一个普通套接字时,您应该在绑定该套接字时指定端口和ip,这样您就知道消息到达的端口(因为您在绑定套接字时设置了该端口)。你能更详细地解释一下你的情况吗?这是真的,但我们可以对目标IP说同样的话,它可以在msghdr
中找到。我们的threadpool设计意味着我们可能会面临无法将端口与其对应的传入数据包正确匹配的风险,读取数据包头将是更安全的方法。