The timer and recvfrom functions are required to collect broadcast information in the 5 s cycle. In the practical process, it is found that the program is still in the blocking status, I have been struggling for a long time before I find the problem. Mark it here for future review.
In the final analysis, the reason is that the signal () function is used: Signal () is the restart function. After the timeout, the blocked function is automatically started, instead of interrupting its execution, such as recvfrom, it seems that alarm is used, but it is still blocked on recvfrom and will not be executed. However, when printing a message using the printf function in the interrupt processing function, you will find that the message is actually interrupted, but the returned message is blocked on recvfrom.
With the sigaction function, you can set whether to restart the function, that is, alarmact. sa_flags = sa_nomask; option. It will interrupt the blocked function and make the program continue to run. The sa_restart option is equivalent to signal and will restart the function and block the recvfrom.
#include <stdio.h>#include <string.h>#include <signal.h>#include <sys/socket.h>#include <errno.h>#include <netinet/in.h>int n;char recvbuf[1024];void listen_board();static void dealSigAlarm(int sigo){ n = -1; printf("alarm interrupt!\n"); return;//just interrupt the recvfrom()}void main(){ struct sigaction alarmact;// signal(SIGALRM,dealSigAlarm); bzero(&alarmact,sizeof(alarmact)); alarmact.sa_handler = dealSigAlarm;// alarmact.sa_flags = SA_RESTART; alarmact.sa_flags = SA_NOMASK; sigaction(SIGALRM,&alarmact,NULL); listen_board();}void listen_board(){ int sock; struct sockaddr_in fromaddr; int len = sizeof(struct sockaddr_in); bzero(&fromaddr,len); fromaddr.sin_family = AF_INET; fromaddr.sin_addr.s_addr = htonl(INADDR_ANY); fromaddr.sin_port = htons(9000); if((sock = socket(AF_INET,SOCK_DGRAM,0)) == -1 ) { perror("socket create error.\n"); } while(1) { alarm(5); n = recvfrom(sock,recvbuf,1024,0,(struct sockaddr *)&fromaddr,&len); if(n < 0) { if(errno == EINTR) printf("recvfrom timeout.\n"); else printf("recvfrom error.\n"); } else alarm(0); }}
Run the program according to the preceding steps. The result is shown in (the interrupt function is called and the recvfrom function is terminated ):
When alarmact. sa_flags = sa_restart; is set, the result is as follows ):
Another: Signal Processing Process: If a signal processing function is set, when the signal arrives, the control flow is switched to the signal processor. After returning from the signal processor, continue to execute the original control flow.
References: http://liuzhigong.blog.163.com/blog/static/178272375201172021328123/
Use alarm () to set a timer for recvfrom