Unix Network Programming Episode 101

#include "unp.h"

ssize_t read_cred(int, void *, size_t, struct cmsgcred *);

void str_echo(int sockfd)
{
    ssize_t n;
    int i;
    char buf[MAXLINE];
    struct cmsgcred cred;

again:
    while((n=read_cred(sockfd, buf, MAXLINE, &cred))>0)
    {
        if(cred.cmcred_ngroups==0)
        {
            printf("(no creantials returned)\n");
        }
        else
        {
            printf("PID of sender=%d\n", cred.cmcred_pid);
            printf("real user ID=%d\n", cred.cmcred_uid);
            printf("real group ID=%d\n", cred.cmcred_gid);
            printf("effective user ID=%d\n", cred.cmcred_euid);
            printf("%d groups:", cred.cmcred_ngroups-1);
            for(i=1;i<cred.cmcreed_ngroups;i++)
                printf(" %d", cred.cmcred.groups[i]);
            printf("\n");
        }

        Writen(sockfd, buf, n);
    }

    if(n<0&& errno==EINTR)
        goto agian:
    else if(n<0)
        err_sys("str_echo: read error");

str_echo function: asks for client’s credentials

Nonblocking I/O

Introduction
By default, sockets are blocking. This means that when we issue a socket call that cannot be completed immediately, our process is put to sleep, waiting for the condition to be true. We can divide the socket calls that may block into four categories:

1.Input operations— These include the read, readv, recv, recvfrom, and recvmsg functions. If we call one of these input functions for a blocking TCP socket (the default), and there is no data available in the socket receive buffer, we are put to sleep until some data arrives. Since TCP is a byte stream, we will be awakened when “some” data arrives: It could be a single byte of data, or it could be a full TCP segment of data. If we want to wait until some fixed amount of data is available, we can call our own function readn (Figure 3.15(See 8.1.9)) or specify the MSG_WAITALL flag (Figure 14.6(See 9.3.3)).
2.Output operations— These include the write, writev, send, sendto, and sendmsg functions. For a TCP socket, we said in Section 2.11(See 7.2.11) that the kernel copies data from the application’s buffer into the socket send buffer. If there is no room in the socket send buffer for a blocking socket, the process is put to sleep until there is room.
3.Accepting incoming connections— This is the accept function. If accept is called for a blocking socket and a new connection is not available, the process is put to sleep.
If accept is called for a nonblocking socket and a new connection is not available, the error EWOULDBLOCK is returned instead.
4.Initiating outgoing connections— This is the connect function for TCP. (Recall that connect can be used with UDP, but it does not cause a “real” connection to be established; it just causes the kernel to store the peer’s IP address and port number.) We showed in Section 2.6(See 7.2.6) that the establishment of a TCP connection involves a three-way handshake and the connect function does not return until the client receives the ACK of its SYN. This means that a TCP connect always blocks the calling process for at least the RTT to the server.

#include "unp.h"

ssize_t read_cred(int, void *, size_t, struct cmsgcred *);

void str_cli(int sockfd)
{
    int maxfpdl, val, stdineof;
    ssize_t n, nwritten;
    fd_set rset, wset;
    char to[MAXLINE], fr[MAXLINE];
    char *toiptr, *tooptr, *fript, *froptr;

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

    val=Fcntl(STDIN_FILENO, F_GETFL, 0);
    Fcntl(STDIN_FILENO, F_SETFL, val |O_NONBLOCK);

    toiptr=tooptr=to;
    friptr=froptr=fr;
    stdineof=0;

    maxfdp1=max(max(STDIN_FILENO, STDOUT_FILENO), sockfd)+1;
    for( ; ;)
    {
        FD_ZERO(&rset);
        FD_ZERO(&wset);
        if(stdineof==0&&toiptr<&to[MAXLINE])
            FD_SET(STDIN_FILENO, &rset);
        if(friptr<&fr[MAXLINE])
            FD_SET(sockfd, &rset);
        if(tooptr!=toiptr)
            FD_SET(sockfd, &wset);
        if(froptr!=friptr)
            FD_SET(STDOUT_FILENO, &wset);

        Select(maxfdp1, &rset, &wset, NULL, NULL);
    }
    
}

Nonblocking Reads and Writes: ‘str_cli’ Function

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值