简体   繁体   English

Asio UDP 套接字接收失败

[英]Asio UDP socket receive failed

Tried this code to send/receive with Asio UDP sockets (boost less version)尝试使用此代码使用 Asio UDP 套接字发送/接收(boost less 版本)

asio::io_service service;
asio::ip::udp::socket sock(service);
asio::ip::udp::endpoint endpoint(asio::ip::address::from_string("127.0.0.1"), 20100);

sock.connect(endpoint);
sock.send(buffer("testing\n"));

std::string buffer;
size_t length = sock.receive(asio::buffer(buffer)); <--- spawn exception

but got following error:但出现以下错误:

An existing connection was forcibly closed by the remote host

Something wrong here?这里有什么问题吗? Thanks for any help!谢谢你的帮助!

I don't know how you build your udp server, but I guess something wrong with it.我不知道你是如何构建 udp 服务器的,但我猜它有问题。 I write an example program to explain the error message you get:我编写了一个示例程序来解释您收到的错误消息:

#include <stdio.h>  
#include <errno.h>  
#include <stdlib.h>  
#include <string.h>  
#include <sys/types.h>  
#include <sys/socket.h>  
#include <netinet/in.h>  
#include <arpa/inet.h>  

int main()  
{    
    struct sockaddr_in addr;  
    int fd, cnt, ret;  

    if ((fd=socket(AF_INET, SOCK_DGRAM, 0)) < 0) {  
        printf("error");
        exit(1);  
    }

    memset(&addr, 0, sizeof(addr));  
    addr.sin_family=AF_INET;  
    addr.sin_addr.s_addr=inet_addr("127.0.0.1");
    addr.sin_port=htons(9090); // address which is not bound

    ret = connect(fd,(struct sockaddr *)&addr,sizeof(addr));  
    char buf[512];

    cnt =  send(fd, "hello", sizeof("hello"), 0);  
    if(cnt < 0)  
        perror("send:");  
    cnt = recv(fd, buf, 512, 0); // error: Connection refused
    if(cnt < 0)  
        perror("recv:");  

     return 0;  
} 

I try to send data to udp port 9090 at localhost or any host which no udp socket is bound to port 9090. the send() succeeds but the recv() fails.我尝试将数据发送到本地主机上的 udp 端口​​ 9090 或任何没有 udp 套接字绑定到端口 9090 的主机。 send()成功但recv()失败。 According to man page for udp :根据udp 的手册页

All fatal errors will be passed to the user as an error return even when the socket is not connected.即使套接字未连接,所有致命错误也将作为错误返回传递给用户。 This includes asynchronous errors received from the network.这包括从网络接收到的异步错误。 You may get an error for an earlier packet that was sent on the same socket.对于在同一套接字上发送的较早数据包,您可能会收到错误消息。 This behaviour differs from many other BSD socket implementations which don't pass any errors unless the socket is connected.此行为不同于许多其他 BSD 套接字实现,除非套接字已连接,否则它们不会传递任何错误。 Linux's behaviour is mandated by According to the rfc 1122 Linux 的行为由根据rfc 1122 规定

which says:其中说:

UDP MUST pass to the application layer all ICMP error messages that it receives from the IP layer. UDP 必须将它从 IP 层接收到的所有 ICMP 错误消息传递给应用层。 Conceptually at least, this may be accomplished with an upcall to the ERROR_REPORT routine至少从概念上讲,这可以通过调用 ERROR_REPORT 例程来完成

the send() succeeds, but it causes an ICMP error message(you can see it with tcpdump), then recv() sees this error( You may get an error for an earlier packet that was sent on the same socket ), so it fails. send()成功,但它导致 ICMP 错误消息(您可以使用 tcpdump 看到它),然后recv()看到此错误(您可能会收到在同一套接字上发送的较早数据包的错误),因此它失败。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM