I hope somebody can help me with this: I have a UDP socket on which I send
data and then do a select() wiating indefinetely until data is sent back.
An example program copied from a previous newsgroup article attached shows
the kind of thing I'm trying to do.
This program works great on 2.4, exactly how I wish for it to work, however
on the 2.2 kernel the readset fires immediately without blocking. The same
behaviour is exhibited on 2.0.
Unfortunately, this program will have to run on an embedded device where
upgrading the kernel is not an option. So, does anybody know what I'm
doing wrong, and how I can get it to work the way I want with 2.2?
Thanks
--------
Attached file: test_sock.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
int main(int argc, char **argv)
{
int fd = -1;
int dest_port = -1;
int ret = -1;
struct sockaddr_in myaddr;
int addr_size = sizeof(myaddr);
struct hostent *hostname = NULL;
fd_set readSet;
fd_set errSet;
struct timeval timeout;
char buf[512];
if (argc < 3)
{
printf("\nUsage: test hostname port\n\n");
exit(-1);
}
hostname = gethostbyname(argv[1]);
dest_port = atoi(argv[2]);
if (hostname == NULL)
{
printf("Could not resolv hostname\n");
exit(-1);
}
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0)
{
printf("Could not open socket\n");
}
addr_size = sizeof(myaddr);
memset(&myaddr, 0, addr_size);
myaddr.sin_family = AF_INET;
myaddr.sin_port = htons(dest_port);
memcpy(&myaddr.sin_addr, hostname->h_addr_list[0], hostname->h_length);
ret = sendto(fd, "*", 1, 0, (const struct sockaddr *)&myaddr,
sizeof(myaddr));
if (ret < 0)
printf("send returned ret=%d, errno=%d\n", ret, errno);
FD_ZERO(&readSet);
FD_SET(fd, &readSet);
FD_ZERO(&errSet);
FD_SET(fd, &errSet);
ret = select(fd + 1, &readSet, NULL, &errSet, NULL);
if (ret < 0)
printf("select returned ret=%d, errno=%d\n", ret, errno);
if ( FD_ISSET(fd, &readSet) )
printf("readSet fired\n");
if ( FD_ISSET(fd, &errSet) )
printf("errSet fired\n");
if ( (ret > 0) && (FD_ISSET(fd, &readSet)) && (!FD_ISSET(fd, &errSet)) )
{
ret = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&myaddr,
(socklen_t *)&addr_size);
if (ret < 0)
printf("recvfrom returned ret=%d, errno=%d\n", ret, errno);
else
printf("buff is %s\n", buf);
}
close(fd);
return 0;
}