一些套接字辅助

本文详细介绍了在网络编程中如何实现可靠的数据读写操作,包括自定义的readn和writen函数,确保数据能完全发送和接收。同时,深入探讨了如何设置连接超时,使用fcntl和select系统调用结合实现连接状态的非阻塞检查,避免长时间等待无效连接,提高程序的健壮性和效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

#define SA struct sockaddr
ssize_t readn(int fd , void *ptr, size_t n)
{
    size_t left = n;
    char * p = (char *)ptr;
    int nread = 0;
    while (left > 0){
        if((nread = read(fd,p,left)) < 0){
                if(errno == EINTR)
                    nread = 0;
                else
                    return -1;
        }
        else if(nread == 0)
            break;
        left -= nread;
        p += nread;
    }
    return n - left;
}
ssize_t writen(int fd , void * ptr , size_t n)
{
    size_t left = n;
    char * p = (char*)ptr;
    int nwrite = 0;
    while( left > 0){
        if((nwrite = write(fd,p,left)) <= 0){
            if(errno == EINTR && nwrite < 0)
                nwrite = 0;
            else
                return -1;
        }
        left -= nwrite;
        p += nwrite;
    }
    return n - left;
}


int conn_timeout(int sockfd , const struct sockaddr_in * sin, socklen_t socklen, int secs)
{
    int old_flag = fcntl(sockfd,F_GETFL,0);
    if( fcntl(sockfd,F_SETFL,old_flag|O_NONBLOCK) < 0){
        perror("fcntl failed");
        return -1;
    }

    int ret = 0;
    if((ret = connect(sockfd,(SA*)&sin,socklen)) < 0){
        if(errno != EINPROGRESS){
            perror("connect error");
            return -1;
        }
    }
    if(0 == ret)
        goto done;

    fd_set rset,wset;
    FD_ZERO(&rset);
    FD_SET(sockfd,&rset);
    wset = rset;
    struct timeval timeout;
    timeout.tv_sec= secs;
    timeout.tv_usec = 0;
    ret = select(sockfd+1,&rset,&wset,NULL,secs?&timeout:NULL);
    if(ret < 0){
        perror("select error");
        return -1;
    }
    else if( 0 == ret){
        close(sockfd);
        return -1;
    }
    if(!(FD_ISSET(sockfd,&rset) || FD_ISSET(sockfd,&wset))){
        return -1;
    }
    done:
    fcntl(sockfd,F_SETFL,old_flag);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值