参考:http://www.cnblogs.com/chenshuyi/p/3539949.html

多路选择I/O — select模型

其思想在于使用一个集合,该集合中包含需要进行读写的fd,通过轮询这个集合,直到有一个fd可读写,才返回。与阻塞I/O不同的是,阻塞I/O仅使用了一次系统调用,就是对fd的读写,如果没有fd处于就绪状态,则进程一直阻塞,而多路选择I/O使用了两次系统调用,第一次是轮询并返回可读写fd数,第二次是对fd进行读写,阻塞只发生在轮询fd的过程。

select函数的原型(sys/select.h)

1 int select (int __nfds, fd_set *__restrict __readfds,
2          fd_set *__restrict __writefds,
3          fd_set *__restrict __exceptfds,
4          struct timeval *__restrict __timeout);

(1)__nfds

    需轮询的最大文件描述符数。如__nfds = 10,则轮询值为0~9的fd,单个进程中,最多可打开1024个fd,该值在sys/select.h中的FD_SETSIZE定义。用户可通过“ulimit -n”查看该值,通过打印/proc/sys/fs/file-max中的值查看系统可打开的最大fd数。

(2)__readfds,__writefds,__exceptfds

    分别代表用户关心的可读、可写、异常的fd,这三个参数的数据类型是fd_set *,这是一组文件描述符的集合,使用一个位来代表一个fd。

fd_set位向量操作函数包括

1 #define FD_SET(fd, fdsetp)   __FD_SET (fd, fdsetp)   //将指定的fd置1
2 #define FD_CLR(fd, fdsetp)   __FD_CLR (fd, fdsetp)   //将指定的fd清0
3 #define FD_ISSET(fd, fdsetp) __FD_ISSET (fd, fdsetp) //测试fd状态,如被置1,返回非0,否则返回0
4 #define FD_ZERO(fdsetp)      __FD_ZERO (fdsetp)      //将所有的fd清0

(3)__timeout

    timeout的数据类型是timeval结构体。通过填充该结构体,设置超时时间,精确到微妙级,如果该参数设置为NULL,则一直等待,直到有fd可读写。如果tv_sec和tv_usec都设置为0,则轮询完指定fd后,立即返回。

1 struct timeval
2 {
3     __time_t tv_sec;          /* Seconds.  */
4     __suseconds_t tv_usec;    /* Microseconds.  */
5 };

(4)select有三种返回值

-1  :出错

0   :如果设置了超时,在指定时间内没有fd可读写,则返回0,可在此指定相应的超时处理操作。

>0 :返回可读写的fd数

可屏蔽信号的select — pselect

从原型上看,pselect函数与select函数的区别在于设置超时的结构体不同,以及多了个用于屏蔽信号的参数。如果__sigmask设置为NULL,则与select一样。

1 int pselect (int __nfds, fd_set *__restrict __readfds,
2             fd_set *__restrict __writefds,
3             fd_set *__restrict __exceptfds,
4             const struct timespec *__restrict __timeout,
5             const __sigset_t *__restrict __sigmask);

(1)timespec结构体的定义如下,它精确到纳秒级。

1 struct timespec
2 {
3     __time_t tv_sec;         /* Seconds.  */
4     long int tv_nsec;        /* Nanoseconds.  */
5 };

(2)__sigmask实际上是信号的位向量。数据类型是sigset_t,定义如下

 /* A `sigset_t' has a bit for each signal.  */

 # define _SIGSET_NWORDS    ( / ( * sizeof (unsigned long int)))
 typedef struct
 {
     unsigned long int __val[_SIGSET_NWORDS];
 } __sigset_t;

测试代码:

//client
#include <Winsock2.h>
#include <stdio.h>
#pragma comment (lib,"Ws2_32.lib")

#define MAX_LINE 80
#define PORT 8000
typedef int socklen_t;

int main(int argc, char *argv[])
{
    struct sockaddr_in   sin, cin;
    socklen_t addr_len;

    int sockfd, maxfdp;
    char *msg = "client";
    char buf[MAX_LINE];

    fd_set fds;
    struct timeval timeout;
    ;

    memset(&sin, ,sizeof(sin));

    sin.sin_family = AF_INET;
    //inet_pton(AF_INET, "127.0.0.1", &sin.sin_addr);
    sin.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    sin.sin_port = htons(PORT);

    ) {
        perror("fail to create socket.\n");
        exit();
    }

    addr_len = sizeof(cin);

    ) {

        timeout.tv_usec = ;
        timeout.tv_sec = interval;

        FD_ZERO(&fds);
        FD_SET(sockfd, &fds);

        maxfdp = sockfd + ;

        sendto(sockfd, msg, strlen(msg) + , , (struct sockaddr*)&sin, sizeof(sin));

        switch (select(maxfdp, &fds, NULL, NULL, &timeout)) {
        :
            perror("error");
            exit(-);
            break;

        :
            printf("timeout.\n");
            break;

        default:
            if (FD_ISSET(sockfd, &fds)) {

                , () {
                    perror("fail to receive.\n");
                    exit();
                }
                else {
                    printf("receive from server: %s.\n", buf);

                    ) {
                        perror("fail to close.\n");
                        exit();
                    }
                    ;
                }
            }
            break;
        }

    }
    ;
}
//Server#pragma comment (lib,"ws2_32.lib")
#include <Winsock2.h>
#include <stdio.h>
#define MAX_LINE 80
#define PORT 8000

int main(int argc, char *argv[])
{
    struct sockaddr_in sin, cin;
    int addr_len;

    int sockfd, n;
    char *msg = "server";
    char buf[MAX_LINE];

    memset(&sin,, sizeof(sin));

    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = htons(INADDR_ANY);
    sin.sin_port = htons(PORT);

    ) {
        perror("fail to create socket.\n");
        exit();
    }

    n = bind(sockfd, (struct sockaddr*)&sin, sizeof(sin));
    ) {
        perror("fail to bind.\n");
        exit();
    }

    ) {
        addr_len = sizeof(cin);

        recvfrom(sockfd, buf, MAX_LINE, , (struct sockaddr*)&cin, &addr_len);

        sendto(sockfd, msg, strlen(msg) + , , (struct sockaddr*)&cin, addr_len);
    }
}

测试:链接失败。。。

                         

基于select模型的udp客户端实现超时机制的更多相关文章

  1. 基于Select模型通信程序的编写,编译和执行

    任务目标 编写Win32程序模拟实现基于Select模型的两台计算机之间的通信,要求编程实现服务器端与客户端之间双向数据传递.客户端向服务器端发送"计算从1到100的奇数和",服务 ...

  2. 基于Select模型的Windows TCP服务端和客户端程序示例

    最近跟着刘远东老师的<C++百万并发网络通信引擎架构与实现(服务端.客户端.跨平台)>,Bilibili视频地址为C++百万并发网络通信引擎架构与实现(服务端.客户端.跨平台),重新复习下 ...

  3. c#基于事件模型的UDP通讯框架(适用于网络包编解码)

    之前写过一篇关于c#udp分包发送的文章 这篇文章里面介绍的方法是一种实现,可是存在一个缺点就是一个对象序列化后会增大非常多.不利于在网络中的传输. 我们在网络中的传输是须要尽可能的减小传送的数据包的 ...

  4. python 3下基于select模型的事件驱动机制程序

    它的基本原理就是select/epoll这个function会不断的轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程.它的流程如图: 当用户进程调用了select,那么整个 ...

  5. 服务器端升级为select模型处理多客户端

    流程图: select会定时的查询socket查询有没有新的网络连接,有没有新的数据需要读,有没有新的请求需要处理,一旦有新的数据需要处理,select就会返回,然后我们就可以处理相应的数据,sele ...

  6. LwIP应用开发笔记之三:LwIP无操作系统UDP客户端

    前一节我们实现了基于RAW API的UDP服务器,在接下来,我们进一步利用RAW API实现UDP客户端. 1.UDP协议简述 UDP协议全称是用户数据报协议,在网络中它与TCP协议一样用于处理数据包 ...

  7. dubbo(九):timeout超时机制解析

    在网络请求时,总会有各种异常情况出现,我们需要提前处理这种情况.在完善的rpc组件dubbo中,自然是不会少了这一层东西的.我们只需要通过一些简单的配置就可以达到超时限制的作用了. dubbo的设计理 ...

  8. Linux网络通信编程(套接字模型TCP\UDP与IO多路复用模型select\poll\epoll)

    Linux下测试代码: http://www.linuxhowtos.org/C_C++/socket.htm TCP模型 //TCPClient.c #include<string.h> ...

  9. c++下基于windows socket的服务器客户端程序(基于UDP协议)

    前天写了一个基于tcp协议的服务器客户端程序,今天写了一个基于UDP协议的,由于在上一篇使用TCP协议的服务器中注释已经较为详细,且许多api的调用是相同的,故不再另外注释. 使用UDP协议需要注意几 ...

随机推荐

  1. libevent 定时器timer

    libevent是一个基于事件触发的网络库,memcached底层也是使用libevent库. 总体来说,libevent有下面一些特点和优势:* 事件驱动,高性能:* 轻量级,专注于网络: * 跨平 ...

  2. 【玩转Ubuntu】09. Ubuntu上安装apktool

    下载两个文件 到这里 https://code.google.com/p/android-apktool/downloads/list?q=label:Featured下载这个文件  1.  apkt ...

  3. Linux下音频编程-输出音频文件

    程序实现了在Linux下播放Ok.wav的功能.程序首先调用fstat函数获得文件相关信息(主要是文件大小信息).通过malloc函数分配指定的内存空间,并将online.wav读入内存:然后,打开声 ...

  4. android下使用smack需引入的包

    compile 'org.igniterealtime.smack:smack-android:4.2.0-alpha1' compile 'org.igniterealtime.smack:smac ...

  5. Js判断一个单词是否有重复字母

    今天上午刷到一道题,大体是写一个方法判断一个单词中是否有重复的字母(或者说一个字符串中是否有重复的字符).我的思路是一个字符一个字符地遍历,如果发现有重复的停止: function isIsogram ...

  6. 自定义View(9)关于onLayout

    1,何时被调用 当外层容器组件调用其内部组件的layout(l,r,t,b)时,内部组件的onLayout就被调用.与onMeasure类似. 2,注意 onLayout对ViewGroup及子类才有 ...

  7. HNOI2008题目总结

    呜呼..NOI前一个月正式开始切BZOJ了……以后的题解可能不会像之前的零散风格了,一套题我会集中起来发,遇到一些需要展开总结的东西我会另开文章详细介绍. 用了一天的时间把HNOI2008这套题切了… ...

  8. 什么是PHP Guzzle?

    Guzzle是一个使得利用PHP实现发送HTTP 请求,方便和web service集成的PHP 客户端模拟组件.一句话,它就像一个PHP写的浏览器.当你的服务端程序需要作为客户端来访问其他的serv ...

  9. poj 2192 (DP)

    这个题题目意思是给你三个字符串str1,str2,str3.将str3从左自右扫描,去匹配str1和str2中的元素,不可重复,若存在一种匹配方法使得str1和str2都被匹配完全了,则输出yes,否 ...

  10. volley(4) 请求参数:data:[ { bar_remain:XX , bar_code:"XX" , bar_id: XX}], method:GET

    1. 来自于WHCombineBatchFragment.java 2.部分代码 ).).).).port + Url.LABELPRINT + "?data="+strPrint ...