Reputation: 5679
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
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