如何唤醒socket被阻塞的函数
展开全部
最近项目遇到一个问题,程序退出的时候资源没有正常释放。经过调试发现,原来是网络线程一直阻塞,导致一些必要的资源没有被释放,写了几个简单的测试程序调试了一下才明白,原来在Linux下直接close socket的文件描述符,并不会使程序中调用的一些阻塞式的socket函数(比如 read、recvfrom 等)退出阻塞,从而导致无法正常释放资源。简化示例如下。 下面是一个简化的UDP服务程序,首先创建socket对象,然后开启服务线程,将客户端发送过来的数据包回发给客户端。当用户在shell中敲入两次回车后,程序退出。#include #include #include #include #include #include #define SERVER_PORT 8888 #define BUFFER_LEN 256 int g_Exit = 0; void *service( void* arg ) { char buff[BUFFER_LEN]; struct sockaddr clientAddr; int socklen = sizeof(clientAddr); int recvbytes; int socketfd = *((int *)arg); printf("OK, Enter Service!\n"); while(!g_Exit) { recvbytes = recvfrom(socketfd,buff,BUFFER_LEN,0,&clientAddr,&socklen); sendto(socketfd,buff,recvbytes,0,&clientAddr,socklen); } printf("OK, Service Thread Exit!\n"); pthread_exit(NULL);; } int main( int argc,char * argv[] ) { int fd; void *status; struct sockaddr_in serverAddr; pthread_t thr; pthread_attr_t attr; fd = socket(AF_INET,SOCK_DGRAM,0); memset(&serverAddr,0,sizeof(serverAddr)); serverAddr.sin_family = AF_INET; serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); serverAddr.sin_port = htons(SERVER_PORT); bind(fd,(struct sockaddr *)&serverAddr,sizeof(serverAddr)); // create service thread pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); if( pthread_create(&thr,&attr,service,(void *)&fd ) ) { printf("pthread_create fail!\n"); return -1; } // Free attribute pthread_attr_destroy(&attr); // wait user control exit getchar(); getchar(); g_Exit = 1; printf("OK, Waiting For Thread Exit...!\n"); close(fd); // wait for thread exit pthread_join(thr, &status);printf("OK, Exit Main Process !\n"); return 0; } 上述程序,当用户敲两次回车后,显示结果如下: 可以看到,没有打出主进程和服务线程的退出信息,无论是主进程还是服务线程都没有正常退出,由此可见,直接close socket句柄,并不能使 recvfrom 函数退出阻塞。
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询