UDP服务recvfrom函数设置非阻塞

来源:互联网 发布:mac os google chrome 编辑:程序博客网 时间:2024/06/06 16:51



基本概念:

其实UDP的非阻塞也可以理解成和TCP是一样的,都是通过socket的属性去做。

方法一:通过fcntl函数将套接字设置为非阻塞模式

方法二:通过套接字选项SO_RECVTIMEO设置超时。


方法一源码,编译:g++ udp_server.cpp -o server

#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <errno.h>#include <strings.h>#include <stdlib.h>#include <netinet/in.h>#include <arpa/inet.h>#include <fcntl.h>#include <unistd.h>void Perror(const char *s){    perror(s);    exit(EXIT_FAILURE);}//设置非阻塞static void setnonblocking(int sockfd) {    int flag = fcntl(sockfd, F_GETFL, 0);    if (flag < 0) {        Perror("fcntl F_GETFL fail");        return;    }    if (fcntl(sockfd, F_SETFL, flag | O_NONBLOCK) < 0) {        Perror("fcntl F_SETFL fail");    }}int main(){    int sockfd;    int port = 9527;    struct sockaddr_in servaddr, cliaddr;    sockfd = socket(AF_INET, SOCK_DGRAM, 0);    if (sockfd == -1) {        Perror("socket failed:");    }    setnonblocking(sockfd);    bzero(&servaddr, sizeof(servaddr));    servaddr.sin_family = AF_INET;    servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");    servaddr.sin_port = htons(port);    if (bind(sockfd, (sockaddr *)&servaddr, sizeof(servaddr)) == -1) {        Perror("bind failed:");    }    socklen_t len;    for ( ; ; ) {        char mesg[1024] = {};        int n = recvfrom(sockfd, mesg, 1024, 0, (sockaddr *)&cliaddr, &len);        sleep(1);        perror("recvfrom fail: ");    }    return 0;}


方法二源码,编译:g++ udp_server.cpp -o server

#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <errno.h>#include <strings.h>#include <stdlib.h>#include <netinet/in.h>#include <arpa/inet.h>#include <fcntl.h>#include <unistd.h>#include <sys/time.h>void Perror(const char *s){    perror(s);    exit(EXIT_FAILURE);}int main(){    int sockfd;    int port = 9527;    struct sockaddr_in servaddr, cliaddr;    sockfd = socket(AF_INET, SOCK_DGRAM, 0);    if (sockfd == -1) {        Perror("socket failed:");    }    // 设置超时    struct timeval timeout;    timeout.tv_sec = 1;//秒    timeout.tv_usec = 0;//微秒    if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) == -1) {        Perror("setsockopt failed:");    }    bzero(&servaddr, sizeof(servaddr));    servaddr.sin_family = AF_INET;    servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");    servaddr.sin_port = htons(port);    if (bind(sockfd, (sockaddr *)&servaddr, sizeof(servaddr)) == -1) {        Perror("bind failed:");    }        socklen_t len;    for ( ; ; ) {        char mesg[1024] = {};        int n = recvfrom(sockfd, mesg, 1024, 0, (sockaddr *)&cliaddr, &len);        perror("recvfrom fail: ");    }    return 0;}


原文出自:http://blog.csdn.net/daiyudong2020/article/details/70039409


End;

1 0
原创粉丝点击