I am trying to send a string HI to a server over UDP in a particular port and then to receive a response. However, after I try to get the response using recvfrom() I was stuck in blocking state. I tried using connected UDP but I got:
Error receiving in UDP: Connection refused
What could be the reasons for this? The server is not under my control, but I do know its working fine.
I have added the code
int sockfdudp;
char bufudp[MAXDATASIZE], port[6];
struct addrinfo hints, *servinfo, *p;
struct sockaddr_storage addr;
int rv;
char s[INET6_ADDRSTRLEN];
int bytes_recv, bytes_sent;
socklen_t len;
scanf("%s",port);
printf("UDP Port: %s \n", port);
// Start connecting to datagram server
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
if ((rv = getaddrinfo(SERVER_NAME, port, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
// loop through all the results and make a socket
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfdudp = socket(p->ai_family, p->ai_socktype,
p->ai_protocol)) == -1) {
perror("Creating datagram socket");
continue;
}
if (connect(sockfdudp, p->ai_addr, p->ai_addrlen) == -1) {
close(sockfdudp);
perror("Connecting stream socket");
continue;
}
break;
}
if (p == NULL) {
fprintf(stderr, "ClientUDP: failed to bind socket\n");
return 2;
}
freeaddrinfo(servinfo);
if ((bytes_sent = sendto(sockfdudp, UDP_MSG, strlen(UDP_MSG), 0, p->ai_addr, p->ai_addrlen)) == -1) {
perror("ClientUDP: Error sending data");
exit(1);
}
printf("Data %s sent\n", UDP_MSG );
len = sizeof(struct sockaddr_storage);
if ((bytes_recv = recvfrom(sockfdudp, bufudp, MAXDATASIZE-1, 0,(struct sockaddr*)&addr, &len)) == -1) {
perror("Error receiving in UDP");
exit(1);
}
printf("Bytes recv %d\n", bytes_recv);
bufudp[bytes_recv] = '\0';
printf("ClientUDP: Received\n %s \n",bufudp );
close(sockfdudp);
return 0;
Chances are your're sending something to a server who does not listen on that particular port.
That would cause an icmp message to be sent back , and your next recvfrom will return an error in the case where you connect the socket.
Check with tcpdump or wireshark what's going on on the wire.
My guess would be that your ip address is bad somehow, or the port is already in use somehow. UDP is connectionless, so there really isn't any "connection" to fail.
Related
Trying to create a server-client application, and I'm having quite a bit of trouble setting up the connection on the server-side. After setting up the socket, and bind()ing the socket, my listen()-call fails with the error message
listen: Invalid argument
which I get from perror()-ing the case where listen() returns -1.
The synopsis of the program is the following: I use getaddrinfo() to generate a linked list of struct addrinfo's, loop through that until I find one that I can successfully create a socket with, then bind() and finally listen().
The listen() call goes as follows:
if ((status = listen(socket_fd, BACKLOG_SIZE)) == -1) {
perror("listen");
close(socket_fd);
freeaddrinfo(res);
exit(EXIT_FAILURE);
}
To be sure, I've printed the values of socket_fd and BACKLOG_SIZE, turning out to be 3 and 5, respectively. Have been debugging for hours now, and I simply cannot find out where the problem lies. Haven't found anyone with the same issue on stackOverflow, either...
Thank you in advance for any help!
Full program:
int main(int argc, char* argv[]) {
int port_no = server_usage(argc, argv);
ready_connection(port_no);
/* Synopsis:
getaddrinfo()
socket()
bind()
listen()
accept()
*/
int socket_fd = setup_socket(NULL, port_no);
struct sockaddr_storage their_addr;
socklen_t addr_size = sizeof(their_addr);
int new_fd = 0;
// Allow reuse of sockets
int activate=1;
setsockopt(socket_fd, IPPROTO_TCP, TCP_NODELAY, &activate, sizeof(int));
if ((status = bind(socket_fd, res->ai_addr, res->ai_addrlen)) == -1) {
perror("bind");
exit(EXIT_FAILURE);
}
if ((status = connect(socket_fd, res->ai_addr, res->ai_addrlen)) == -1) {
perror("connect");
close(socket_fd);
freeaddrinfo(res); // free the linked-list
exit(EXIT_FAILURE);
}
if ((status = listen(socket_fd, BACKLOG_SIZE)) == -1) {
perror("listen");
close(socket_fd);
freeaddrinfo(res); // free the linked-list
exit(EXIT_FAILURE);
}
if ((new_fd == accept(socket_fd, (struct sockaddr *)&their_addr, &addr_size)) == -1) {
perror("accept");
exit(EXIT_FAILURE);
}
char buffer[BUFSIZE];
recv(new_fd, buffer, BUFSIZE, 0);
close(socket_fd);
close(new_fd);
freeaddrinfo(res); // free the linked-list
return 0;
}
setup_socket()-function:
int setup_socket(char* hostname, int port_no) {
// hints is mask struct, p is loop variable
struct addrinfo hints, *p;
memset(&hints, 0, sizeof hints); // make sure the struct is empty
// TODO IPv6-support?
hints.ai_family = AF_INET; // only IPv4 supported
hints.ai_socktype = SOCK_STREAM; // TCP stream sockets
hints.ai_flags = AI_PASSIVE; // fill in my IP for me
char port_str[6]; // max port size is 5 digits + 0-byte
memset(port_str, 0, 6);
sprintf(port_str, "%d", port_no);
if ((status = getaddrinfo(hostname, port_str, &hints, &res)) == -1) {
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
exit(EXIT_FAILURE);
}
int socket_fd = 0;
for (p = res; p != NULL; p = p->ai_next) {
if ((socket_fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
}
if (socket_fd == 0) {
errno = ENOTSOCK;
perror("no socket");
exit(EXIT_FAILURE);
}
return socket_fd;
}
You cannot connect(), then listen() on the same socket. Lose the connect().
Basically my server/client socket functions work perfectly fine using the loopback address, or even my eth0 address on my laptop. Howver, once I move my code into the test environment it will be used in, I get connection time outs, or connection refused depending on the changes I have tried to make.
As of now the code I am about to post results in a Connection time out.
CLIENT
void buildConnection(int* txmt_sock, Connection conn_info)
{
struct sockaddr_in servinfo; /* server address */
servinfo.sin_family = AF_INET;
servinfo.sin_addr.s_addr = INADDR_ANY;
servinfo.sin_port = htons(conn_info.port);
if(inet_aton(conn_info.ip, &servinfo.sin_addr) < 1)
{
fprintf(stderr, "Read error: %s\n", strerror(errno));
abort();
}
/*int socket(int domain, int type, int protocol)*/
if ((*txmt_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("client: socket");
abort();
}
/*int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);*/
if (connect(*txmt_sock,(struct sockaddr *)&servinfo,(socklen_t)sizeof(servinfo)) == -1)
{
close(*txmt_sock);
perror("client: connect");
abort();
}
printf("Successfully connected on port %s:%d\n", conn_info.ip, conn_info.port);
}
SERVER
void returnConnection(Connection* conn_info)
{
int status, ext_conn, yes = 1;
char portStr[5];
struct addrinfo hints, *servinfo;
struct sockaddr_storage ext_addr;
socklen_t addr_size;
struct sockaddr *restrict;
/* Formats PORT for use with getaddrinfo(), can't cast #define*/
snprintf(portStr, 6, "%d", conn_info->port);
memset(&hints, 0, sizeof(hints)); /*make sure the struct is empty*/
hints.ai_family = AF_UNSPEC; /*don't care IPv4 or IPv6*/
hints.ai_socktype = SOCK_STREAM; /*TCP stream sockets*/
hints.ai_flags = AI_PASSIVE; /*fill in my IP for me*/
if ((status = getaddrinfo(NULL, portStr, &hints, &servinfo)) != 0)
{
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
exit(1);
}
if((conn_info->listen_sock = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol)) == -1)
{
fprintf(stderr, "Socket error: %s\n", strerror(errno));
exit(1);
}
if(setsockopt(conn_info->listen_sock,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1)
{
perror("setsockopt");
exit(1);
}
if(bind(conn_info->listen_sock, servinfo->ai_addr, servinfo->ai_addrlen) == -1)
{
fprintf(stderr, "Bind error: %s\n", strerror(errno));
exit(1);
}
freeaddrinfo(servinfo);
if(listen(conn_info->listen_sock, 1) == 1)
{
fprintf(stderr, "Listening error: %s\n", strerror(errno));
exit(1);
}
addr_size = sizeof(ext_conn);
if((ext_conn = accept(conn_info->listen_sock, (struct sockaddr *)&ext_addr, &addr_size)) == -1)
{
fprintf(stderr, "Accept error: %s\n", strerror(errno));
exit(1);
};
conn_info->receiving_sock = ext_conn;
}
This is a multi-threaded program that collects image data from 8 different ports/threads. I use my Connection struct to store all the pertinent data for each thread. Each thread has it's own Connection.
typedef struct connection{
char* file;
int port;
char* ip;
pthread_t *thread;
}Connection;
Connection->ip is not used in the server side, but is uses on the Client side. The server side of the code resides on a multi-cpu, multi-nic IBM server. I am not certain if I need to manually assign the IP or not because of that. I am assuming the OS and network cards manage on their own using the incoming PORT numbers from the clients, and the individual PORT numbers that my Server threads listen on. But all I know is that it works on my laptop to itself.
It's a completely new vanilla install on this machine with openSuse, so I don't think any of the ports I am using, 5050-5053 and 5055-5058, are turned off or anything like that.
Firstly please bear me with the long question - I'm writing a UDP client-server program and odd enough I had this packet loss problem whenever I use this flag for protocol family. Symptom is packets never left the sender host (no captures from tcpdump) but sendto() returns the correct positive value, which is never bigger than 200 bytes. It took me a ridiculous amount of time to figure out this can be resolved by forcing IPv4 but I don't understand why? It's been tested numerous times with server and client running on the same system (scientific linux 6) so the common unreliable UDP transmission is probably not the cause here, nor is there any firewall rule that drops anything at all. I'm wondering if anyone happens to know the cause? Also I thought about posting some code but it doesn't seem to be necessary.. Simply put, AF_UNSPEC results in all UDP packets never leaving the sender but no error, and with AF_INET everything is perfect. This might be a weird question but any insight is appreciated. Thanks a lot!Code for server initialization:
int udp_srv_init(char * port)
{
struct addrinfo hints, *servinfo, *p;
int rv;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;
if ((rv = getaddrinfo(NULL, port, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return EXIT_FAILURE;
}
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((self_udp = socket(p->ai_family, p->ai_socktype,
p->ai_protocol)) == -1) {
perror("socket");
continue;
}
if (bind(self_udp, p->ai_addr, p->ai_addrlen) == -1) {
close(self_udp);
fprintf(stderr, "Port %s: ",port);
perror("bind");
continue;
}
break;
}
if (p == NULL) {
fprintf(stderr, "server: failed to bind socket\n");
return EXIT_FAILURE;
}
freeaddrinfo(servinfo);
int buffsize = 65536; // I added this because I thought it was some buffer problem, but didn't change a thing
setsockopt(self_udp, SOL_SOCKET, SO_RCVBUF, (void*)&buffsize, sizeof(buffsize));
return EXIT_SUCCESS;
}
and for sending:
//...
for(i=0; i<num_neighbors; i++)
{
if(neighbors[i].cost == -1)
continue;
int bytes_sent = 0, ret;
while(bytes_sent < packet_size)
{
if(-1 == (ret = sendto(neighbors[i].skt, (void*)&my_neighs +
(ptrdiff_t)bytes_sent, packet_size-bytes_sent,
0, neighbors[i].p->ai_addr, neighbors[i].p->ai_addrlen)))
{
perror("sendto1");
return EXIT_FAILURE;
}
bytes_sent += ret;
}
}
//....
neighbors is a structure array with elements that have member fields:
struct addrinfo *servinfo, *p;
They are obtained from socket initialization, and freeaddrinfo() is only called at the very end of program execution so they are all valid.
I'm trying to listen to DNS request of browsers on my localhost.
I've wrote this code:
WSADATA wsaData;
unsigned char hostname[100];
int sockfd;
struct addrinfo hints, *servinfo, *p;
int rv;
int numbytes;
struct sockaddr_storage their_addr;
char buf[1000];
socklen_t addr_len;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE; // use my IP
if (WSAStartup(MAKEWORD(2,0), &wsaData) != 0)
{
fprintf(stderr, "WSAStartup failed.\n");
exit(1);
}
if ((rv = getaddrinfo(NULL, "53", &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
// loop through all the results and bind to the first we can
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfd = socket(AF_INET, SOCK_DGRAM,IPPROTO_UDP)) == -1) {
perror("listener: socket");
continue;
}
if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
closesocket(sockfd);
perror("listener: bind");
continue;
}
break;
}
if (p == NULL) {
fprintf(stderr, "listener: failed to bind socket\n");
return 2;
}
freeaddrinfo(servinfo);
printf("listener: waiting to recvfrom...\n");
addr_len = sizeof their_addr;
if ((numbytes = recvfrom(sockfd, buf, 1000-1 , 0,(struct sockaddr *)&their_addr, &addr_len)) == -1) {
perror("recvfrom");
exit(1);
printf("listener: packet is %d bytes long\n", numbytes);
buf[numbytes] = '\0';
printf("listener: packet contains \"%s\"\n", buf);
}
closesocket(sockfd);
I get some weird packets of 39 bytes with some characters I can't read...And it's always getting packets on 53 also when not surfing to anything, is this not the good way to listen to dns requests?
I've changed my DNS Ip to 127.0.0.1 on windows.
Kind regards,
DNS is not a text-based protocol like HTTP, you are supposed to decode the packets. Look into RFC 1035 for details.
I've parsed like this:
pointer = substring( buffer, 14, numbytes-18);
//printf("Substring: %s \n",pointer);
//printf("listener: packet contains \"%x\"\n", buffer);
for( i = 0; i < strlen(pointer); i++)
{
// Indien kleiner als 32 dan moet het een . worden
if(pointer[i] < 32)
result[i] = '.';
// Indien groeter als 32 en kleiner als 127 is het een char
else if(pointer[i] > 32 && pointer[i] < 127)
result[i] = (char)(pointer[i]);
else
continue;
}
result[i] = '\0';
Then in your result you have something like "www.google.com".
I am using raw sockets with TCP. Whenever a packet gets sent to me, my computer send a RST packet back. I tried http://udi.posterous.com/suppressing-tcp-rst-on-raw-sockets, which isn't working:
int main(void) {
struct addrinfo *info, hints, *p;
int status, sock;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
status = getaddrinfo(NULL, "3000", &hints, &info);
if (status != 0) function_error("getaddrinfo", 1);
for (p = info; p; p = p->ai_next) {
sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
if (sock == -1) continue;
if (bind(sock, p->ai_addr, p->ai_addrlen) == -1) continue;
break;
}
if (p == NULL) {
fprintf(stderr, "Can't connect. Error = %d\n", errno);
return 2;
}
freeaddrinfo(info);
if (listen(sock, 10) == -1)
function_error("listen", 3);
while (1) sleep(60);
close(sock);
return 0;
}
void function_error(char *func, int code) {
fprintf(stderr, "%s error: %d\n", func, errno);
exit(code);
}
How can I get it to stop? Do I need to use that code in the same process I am using the raw socket in?