Reputation: 288
I managed to make a reproducible example (All includes from my large original source code remain). The thing is that only the first letter a
is sent. Then, I get send() failed: Connection refused
. I don't know what to do, this is literally the smallest code that should work.
I should say that the code does not work only if I open the socket once at the beginning of the program and close it at the end of the program. If I open a socket for each individual send() and then close it right afterwards, no error comes up.
#include <pcap.h>
#include <cstdio>
#include <getopt.h>
#include <cstring>
#include <cstdlib>
#include <string>
#include <iostream>
#include <map>
#include <vector>
#define BUFSIZE 256
#define __FAVOR_BSD
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include<netdb.h>
#include<err.h>
#include <arpa/inet.h>
#include <netinet/ether.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>
#include <netinet/icmp6.h>
using namespace std;
#define BUFFER 1024 // buffer length
int sock; // socket descriptor
void start_connection(){
struct sockaddr_in server, from; // address structures of the server and the client
struct hostent *servent; // network host entry required by gethostbyname()
memset(&server,0,sizeof(server)); // erase the server structure
server.sin_family = AF_INET;
// make DNS resolution of the first parameter using gethostbyname()
if ((servent = gethostbyname("127.0.0.1")) == NULL) // check the first parameter
errx(1,"gethostbyname() failed\n");
// copy the first parameter to the server.sin_addr structure
memcpy(&server.sin_addr,servent->h_addr,servent->h_length);
server.sin_port = htons(2055);
if ((sock = socket(AF_INET , SOCK_DGRAM , 0)) == -1) //create a client socket
err(1,"socket() failed\n");
// create a connected UDP socket
if (connect(sock, (struct sockaddr *)&server, sizeof(server)) == -1)
err(1, "connect() failed");
}
void send_data(char * string){
char buffer[BUFFER];
int msg_size,i;
//send data to the server
memcpy(buffer,string,2);
msg_size=2;
i = send(sock,buffer,msg_size,0); // send data to the server
if (i == -1) // check if data was sent correctly
err(1,"send() failed");
else if (i != msg_size)
err(1,"send(): buffer written partially");
printf("%s",string);
}
int main(int argc, char *argv[])
{
//Start UDP connection
start_connection();
send_data("a");
send_data("b");
send_data("c");
//Close the UDP connection
close(sock);
return 0;
}
Upvotes: 0
Views: 340
Reputation: 123260
UDP does not provide a real reliable connection. connect
just sets the destination address. A send
will only put the data into the send buffer and will only fail if there was a previous error on the socket.
The first send
will not fail, since no previous activity was done on the socket and thus not error could have happend.
But ... the datagram is then send to the target system. If the target system or some firewall in between rejects the packet with ICMP unreachable, then an error will be set on the socket. This error will then be delivered to the application on the next system call on the socket - in this case the second send
.
Thus, what you observe will for example happen if there is no UDP server expecting packets on the specific IP and port or if some firewall is explicitly blocking the packets. As explained, you get the error only on the second send
.
Upvotes: 7