leon22
leon22

Reputation: 5679

Asio UDP socket receive failed

Tried this code to send/receive with Asio UDP sockets (boost less version)

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!

Upvotes: 2

Views: 953

Answers (1)

jfly
jfly

Reputation: 8020

I don't know how you build your udp server, but I guess something wrong with it. 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. According to man page for 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. Linux's behaviour is mandated by According to the rfc 1122

which says:

UDP MUST pass to the application layer all ICMP error messages that it receives from the IP layer. Conceptually at least, this may be accomplished with an upcall to the ERROR_REPORT routine

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.

Upvotes: 1

Related Questions