Unix Network Programming Episode 96

‘socketpair’ Function

The socketpair function creates two sockets that are then connected together. This function applies only to Unix domain sockets.

#include <sys/socket.h>
int socketpair(int family, int type, int protocol, int sockfd[2]);

POSIX does not require full-duplex pipes. On SVR4, pipe returns two full-duplex descriptors, while Berkeley-derived kernels traditionally return two half-duplex descriptors (Figure 17.31 of TCPv3).

Socket Functions

There are several differences and restrictions in the socket functions when using Unix domain sockets. We list the POSIX requirements when applicable, and note that not all implementations are currently at this level.

1.The default file access permissions for a pathname created by bind should be 0777 (read, write, and execute by user, group, and other), modified by the current umask value.
2.The pathname associated with a Unix domain socket should be an absolute pathname, not a relative pathname. The reason to avoid the latter is that its resolution depends on the current working directory of the caller. That is, if the server binds a relative pathname, then the client must be in the same directory as the server (or must know this directory) for the client’s call to either connect or sendto to succeed.
POSIX says that binding a relative pathname to a Unix domain socket gives unpredictable results.
3.The pathname specified in a call to connect must be a pathname that is currently bound to an open Unix domain socket of the same type (stream or datagram). Errors occur if: (i) the pathname exists but is not a socket; (ii) the pathname exists and is a socket, but no open socket descriptor is associated with the pathname; or (iii) the pathname exists and is an open socket, but is of the wrong type (that is, a Unix domain stream socket cannot connect to a pathname associated with a Unix domain datagram socket, and vice versa).
4.The permission testing associated with the connect of a Unix domain socket is the same as if open had been called for write-only access to the pathname.
5.Unix domain stream sockets are similar to TCP sockets: They provide a byte stream interface to the process with no record boundaries.
6.If a call to connect for a Unix domain stream socket finds that the listening socket’s queue is full (Section 4.5(See 8.2.5)), ECONNREFUSED is returned immediately. This differs from TCP: The TCP listener ignores an arriving SYN if the socket’s queue is full, and the TCP connector retries by sending the SYN several times.
7.Unix domain datagram sockets are similar to UDP sockets: They provide an unreliable datagram service that preserves record boundaries.
8.Unlike UDP sockets, sending a datagram on an unbound Unix domain datagram socket does not bind a pathname to the socket. (Recall that sending a UDP datagram on an unbound UDP socket causes an ephemeral port to be bound to the socket.) This means the receiver of the datagram will be unable to send a reply unless the sender has bound a pathname to its socket. Similarly, unlike TCP and UDP, calling connect for a Unix domain datagram socket does not bind a pathname to the socket.

Unix Domain Stream Client/Server

We now recode our TCP echo client/server from Chapter 5(See 8.3) to use Unix domain sockets. Figure 15.3 shows the server, which is a modification of Figure 5.12(See 8.3.10) to use the Unix domain stream protocol instead of TCP.

#include "unp.h"

int main(int argc, char **argv)
{
    int listenfd, connfd;
    pid_t childpid;
    socklen_t clientlen;
    struct sockaddr_un clientaddress, serveraddress;
    void sig_child(int);

    listenfd=Socket(AF_LOCAL,SOCK_STREAM,0);

    unlink(UNIXSTR_PATH);
    bzero(&serveraddress,sizeof(serveraddress));
    serveraddress.sun_family=AF_LOCAL;
    strcpy(serveraddress.sun_path,UNIXSTR_PATH);

    Bind(listenfd, (SA *)&serveraddress, sizeof(serveraddress));

    Listen(listenfd, LISTENQ);

    Signal(SIGCHLD, sig_child);

    for(;;)
    {
        clientlen=sizeof(clientaddress);
        if((connfd=accept(listenfd, (SA *)&clientaddress, &clientlen))<0)
        {
            if(errno==EINTR)
                continue;
            else
                err_sys("accept error");
        }

        if((childpid=Fork())==0)
        {
            Close(listenfd);
            str_echo(connfd);
            return 0;
        }
        
        Close(connfd);
    }

    return 0;
}

Unix domain stream protocol echo server

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值