Unix Network Programming Episode 103

#include "unp.h"

void str_client(FILE *fp, int sockfd)
{
    pid_t pid;
    char sendline[MAXLINE], recvline[MAXLINE];

    if((pid=Fork())==0)
    {
        while(Readline(socfd, recvline, MAXLINE)>0)
            Fputs(recvline, stdout);

            kill(getppid(), SIGTERM);
            return;
    }

    while(Fgets(sendline, MAXLINE, fp)!=NULL)
        Writen(sockfd, sendline, strlen(sendline));
    
    Shutdown(sockfd, SHUT_WR);
    pause();
    return;
}

Version of str_cli function that uses fork

Nonblocking ‘connect’

When a TCP socket is set to nonblocking and then connect is called, connect returns immediately with an error of EINPROGRESS but the TCP three-way handshake continues. We then check for either a successful or unsuccessful completion of the connection’s establishment using select. There are three uses for a nonblocking connect:

1.We can overlap other processing with the three-way handshake. A connect takes one RTT to complete (Section 2.6(See 7.2.6)) and this can be anywhere from a few milliseconds on a LAN to hundreds of milliseconds or a few seconds on a WAN. There might be other processing we wish to perform during this time.
2.We can establish multiple connections at the same time using this technique. This has become popular with Web browsers, and we will show an example of this in Section 16.5(See 9.5.5).
3.Since we wait for the connection to be established using select, we can specify a time limit for select, allowing us to shorten the timeout for the connect. Many implementations have a timeout for connect that is between 75 seconds and several minutes. There are times when an application wants a shorter timeout, and using a nonblocking connect is one way to accomplish this. Section 14.2(See 9.3.2) talks about other ways to place timeouts on socket operations.

As simple as the nonblocking connect sounds, there are other details we must handle:

  • Even though the socket is nonblocking, if the server to which we are connecting is on the same host, the connection is normally established immediately when we call connect. We must handle this scenario.
  • Berkeley-derived implementations (and POSIX) have the following two rules regarding select and nonblocking connects:
    1.When the connection completes successfully, the descriptor becomes writable (p. 531 of TCPv2).
    2.When the connection establishment encounters an error, the descriptor becomes both readable and writable (p. 530 of TCPv2).
Nonblocking ‘connect:’ Daytime Client
#include "unp.h"

int connect_nonb(int sockfd, const SA *saptr, socklen_t salen, int nsec)
{
    int flags, n, error;
    socklen_t len;
    fd_set rset, wset;
    struct timeval val;

    flags=Fcntl(sockfd, F_GETFL, 0);
    Fcntl(sockfd, F_SETFL, flags|O_NONBLOCK);

    error=0;
    if((n=connect(sockfd, saptr, salen))<0)
        if(errno!=ENIPROGRESS)
            return -1;
    
    if(n==0)
        goto done;

    FD_ZERO(&rset);
    FD_SET(sockfd, &rset);
    wset=rset;
    tval.tv_sec=nsec;
    tval.tv_nsec=0;

    IF((n=Select(sockfd+1, &rset, &wset, NULL, nsec?&tval:NULL))==0)
    {
        close(sockfd);
        errno=ETIMEDOUT;
        return -1;
    }
    
    if(FD_ISSET(sockfd, &rset)||FD_ISSET(sockfd, &wset))
    {
        len=sizeof(error);
        if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len)<0)
            return -1;
    }
    else
        err_quit("select error: sockfd not set");

done:
    Fcntl(sockfd, F_SETFL, flags);

    if(error)
    {
        close(sockfd);
        errno=error;
        return -1;
    }
    
    return 0;
}

Issue a nonblocking connect

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值