#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define BUFFER 800
#define SERV_PORT 3333
int main()
{
int sockfd,n;
socklen_t len;
socklen_t src_len;
struct sockaddr_in servaddr, cliaddr;
char msg[BUFFER];
struct timeval tm;
fd_set rd_fd, wr_fd, ex_fd;
sockfd = socket(AF_INET, SOCK_DGRAM, 0); /* create a socket */
/* init servaddr */
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
/* bind address and port to socket */
if(bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1)
perror("bind error");
exit(1);
}
src_len = sizeof(cliaddr);
FD_ZERO(&rd_fd);
FD_SET(sockfd, &rd_fd);
tm.tv_sec = 0;
tm.tv_usec = 0;
while(1)
tm.tv_sec = 1;
if(select(sockfd + 1, &rd_fd, NULL, NULL, &tm) <= 0){
continue;
else
printf("%d, %d/n", tm.tv_sec, tm.tv_usec);
printf("there is data/n");
if(recvfrom(sockfd, msg, BUFFER, 0, (struct sockaddr *)&cliaddr, &src_len)< 0)
perror("receive error!/n");
exit(0);
printf("%s/n", msg);
sleep(5);
return 0;
曾經寫過如上這樣的代碼,執行時怎麼也得不到預想的結果!
後來,仔細看man select
On success, select() and pselect() return the number of file descriptors contained in the three returned descriptor sets(that is, the total number of bits that are set in readfds, writefds, exceptfds) which may be zero if the timeout expires before anything interesting happens. On error, -1 is returned, and errno is set appropriately; the sets and timeout become undefined, so do not rely on their contents after an error.
原來第一次select的時候出錯了,導緻rd_fd和tm(主要是rd_fd)的值 become undefined,進而導緻以後的select調用的失敗!
解決辦法:
在1處(while循環内的開頭),添加如下代碼: