select() not working with UDP
select() not working with UDP
- Subject: select() not working with UDP
- From: email@hidden
- Date: Mon, 29 Jun 2009 23:48:56 -0700
Hello,
My simple UDP packet echoer works without using select(). But, I need to use select() as the complexity of my app increases.
The problem is that select() only returns after the timeout, but not when any UDP data has arrived.
Thanks for any input!
The code is below:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/select.h>
#include <fcntl.h>
#define PORTIN "4701" // the port users will be connecting to
#define PORTOUT "4700" // the port users will be connecting to
#define PORTINNUM 4701
#define PORTOUTNUM 4700
#define MAXBUFLEN 32768
int sockfdIn,sockfdOut;
struct addrinfo *servinfoOutSelect;
void *get_in_addr(struct sockaddr *sa)
{
if (sa->sa_family == AF_INET) {
return &(((struct sockaddr_in*)sa)->sin_addr);
}
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
// prepares for udp input using getaddrinfo
// this method works for recvfrom but select does not work.
int prepIn(void) {
struct addrinfo hints, *servinfoIn, *servinfoInSelect;
int rv;
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 ((rv = getaddrinfo(NULL, PORTIN, &hints, &servinfoIn)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
// loop through all the results and bind to the first we can
for(servinfoInSelect = servinfoIn; servinfoInSelect != NULL; servinfoInSelect = servinfoInSelect->ai_next) {
if ((sockfdIn = socket(servinfoInSelect->ai_family, servinfoInSelect->ai_socktype,
servinfoInSelect->ai_protocol)) == -1) {
perror("listener: socket");
continue;
}
if (bind(sockfdIn, servinfoInSelect->ai_addr, servinfoInSelect->ai_addrlen) == -1) {
close(sockfdIn);
perror("listener: bind");
continue;
}
break;
}
if (servinfoInSelect == NULL) {
fprintf(stderr, "listener: failed to bind socket\n");
return 2;
}
freeaddrinfo(servinfoIn);
return 0;
}
int prepOut(void) {
struct addrinfo hints, *servinfoOut;
int rv;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
if ((rv = getaddrinfo("localhost", PORTOUT, &hints, &servinfoOut)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
// loop through all the results and make a socket
for(servinfoOutSelect = servinfoOut; servinfoOutSelect != NULL; servinfoOutSelect = servinfoOutSelect->ai_next) {
if ((sockfdOut = socket(servinfoOutSelect->ai_family, servinfoOutSelect->ai_socktype,
servinfoOutSelect->ai_protocol)) == -1) {
perror("talker: socket");
continue;
}
break;
}
if (servinfoOutSelect == NULL) {
fprintf(stderr, "talker: failed to bind socket\n");
return 2;
}
return 0;
}
int echo(void)
{
struct {long global;short local;} packetCount;
int numbytes;
struct sockaddr_storage their_addr;
char buf[MAXBUFLEN];
socklen_t addr_len;
#ifdef USE_SELECT
struct timeval tv;
fd_set readfds;
tv.tv_sec = 1;
tv.tv_usec = 0;
FD_ZERO(&readfds);
FD_SET(sockfdIn, &readfds);
#endif
packetCount.global = packetCount.local = 0;
for(;;) {
#ifdef USE_SELECT
while (!select(sockfdIn+1, &readfds, NULL, NULL, &tv))
printf("still waiting %d\n",secCount++);
if (FD_ISSET(sockfdIn, &readfds)) {
#endif
addr_len = sizeof their_addr;
if ((numbytes = recvfrom(sockfdIn, buf, sizeof(buf), 0,(struct sockaddr *)&their_addr, &addr_len)) == -1) {
perror("recvfrom");
exit(1);
}
packetCount.global++;
packetCount.local++;
if (packetCount.local==100){
printf("%d\n",packetCount.global);
packetCount.local = 0;
}
if ((numbytes = sendto(sockfdOut, buf, numbytes, 0,servinfoOutSelect->ai_addr, servinfoOutSelect->ai_addrlen)) == -1) {
perror("talker: sendto");
exit(1);
}
#ifdef USE_SELECT
}
#endif
}
close(sockfdIn);
return 0;
}
int main (int argc, char * const argv[]) {
// insert code here...
std::cout << "Hello, World!\n";
prepIn();
prepOut();
echo();
return 0;
}
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden