Unix Network Programming Episode 89

Advanced I/O Functions

Introduction

This chapter covers a variety of functions and techniques that we lump into the category of “advanced I/O.” First is setting a timeout on an I/O operation, which can be done in three different ways. Next are three more variations on the read and write functions: recv and send, which allow a fourth argument that contains flags from the process to the kernel, readv and writev, which let us specify a vector of buffers to input into or output from, and recvmsg and sendmsg, which combine all the features from the other I/O functions along with the new capability of receiving and sending ancillary data.

Socket Timeouts

There are three ways to place a timeout on an I/O operation involving a socket:

1.Call alarm, which generates the SIGALRM signal when the specified time has expired. This involves signal handling, which can differ from one implementation to the next, and it may interfere with other existing calls to alarm in the process.
2.Block waiting for I/O in select, which has a time limit built-in, instead of blocking in a call to read or write.
3.Use the newer SO_RCVTIMEO and SO_SNDTIMEO socket options. The problem with this approach is that not all implementations support these two socket options.

#include "unp.h"

static void connect_alarm(int);

int connect_timeo(int sockfd, const SA *saptr, socklen_t salen, int nsec)
{
    Sigfunc *sigfunc;
    int n;

    sigfunc=Signal(SIGALRM, connect_alarm);

    if(alarm(nsec)!=0)
        err_msg("connect_timeo:alarm was already set");
    
    if((n=connect(sockfd, saptr, salen))<0)
    {
        close(sockfd);
        if(errno==EINTR)
            errno=ETIMEDOUT;
    }
    alarm(0);
    Signal(SIGALRM, sigfunc);
    
    return n;
}

static void connect_alarm(int signo)
{
    return;
}

connect with a timeout

#include "unp.h"

static void sig_alarm(int);

int dg_client(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
{
    int n;
    char sendline[MAXLINE], recvline[MAXLINE+1];
    Signal(SIGALRM, sig_alrm);

    while(Fgets(sendline,MAXLINE, fp)!=NULL)
    {
        Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
        alarm(5);
        if((n=recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL))<0)
        {
            if(errno==EINTR)
                fprintf(stderr,"socket timeout\n");
            else
                err_sys("recvfrom error");
        }
        else
        {
            alarm(0);
            recvline[n]=0;
            Fputs(recvline, stdout);
        }
    }
}

static void sig_alrm(int signo)
{
    return;
}

dg_cli function with alarm to timeout recvfrom

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值