Cross-process communication using UNIX domain sockets

Source: Internet
Author: User
Tags unix domain socket
Introduction to UNIX domain sockets

UNIX domain sockets are described in advanced Programming for UNIX environments as follows:

Although the Socketpair function creates a pair of sockets that are interconnected, each socket has no name. This means that unrelated processes cannot use them.

We can name the UNIX domain socket and use it for the notice service. Note, however, that Unxi and sockets use different addresses than Internet domain sockets.

The address of a UNIX domain socket is represented by the SOCKADDR_UN structure.

In linux2.4.22, the SOCKADDR_UN structure is defined in the following form as a file

    struct sockaddr_un{
    sa_family_t sun_family;//af_unix
    Char sun_path[108];//pathname
    };

Sun_path members contain all the names, and when we bind an address to a UNIX domain socket, the system uses the pathname to create a s_ifsock file. This file is used only to inform the client process of the socket name. The file cannot be opened, nor can it be used by the application for communication.

If the file already exists when we attempt to bind the address, the bind request fails. When the socket is closed, the file is not automatically deleted, so we must make sure that the file is unlinked before the application terminates.

The server process can use the standard bind, listen, and accept functions to schedule a unique UNIX domain connection for the client process. The client process connects to the server process using Connect;

Once the server process has accepted the Connect request, a unique connection exists between the server process and the client process. This style is similar to the operation of Internet sockets. programming with named UNIX domain socket processes

example provides the ability to implement a Client-server interaction with UNIX domain sockets

The server-side code is as follows: Create a UNIX socket and bind to/tmp/test.sock for listening, and when there is a client connection, the child process is fork to receive the data and print to the screen:

/****************************************************************************** * File name: TestUnixSocket.cpp * File Description: UNIX domain socket Test * Created Date: 2015-04-02 * Author: Casheywen ******************************************************************
/#include <iostream> using namespace std; #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #define L Og_err (FMT, args ...) fprintf (stderr, "pid:%d|") FMT "\ n", Getpid (), # #args) #define LOG_INFO (FMT, args ...) fprintf (stdout, "pid:%d|"
    FMT "\ n", Getpid (), # #args) int createunixsocket (const char *pszpath) {int iFd = socket (Af_unix, sock_stream, 0);
        if (IFd < 0) {Log_err ("Create Socket Fail:%s", Strerror (errno));
    return-1;
    } struct Sockaddr_un staddr;

    memset (&staddr, 0, sizeof (STADDR));
    staddr.sun_family = Af_unix;


    strncpy (Staddr.sun_path, Pszpath, sizeof (Staddr.sun_path)); int iRet = bind (IFd, (struct sockaddr *) &sTADDR, sizeof (STADDR));
        if (IRet < 0) {Log_err ("Bind Fail:%s", Strerror (errno));
    return-1;
return to IFd;

    int main (int argc, char *argv[]) {const char szsocketpath[] = "/tmp/test.sock";
    if (0 = Access (Szsocketpath, F_OK)) {unlink (Szsocketpath);

    int iFd = Createunixsocket (Szsocketpath);
        if (IFd < 0) {Log_err ("Createunixsocket%s Fail", Szsocketpath);
    return 1;

    int iRet = 0;
        while (true) {IRet = Listen (IFd, 5);
            if (IRet < 0) {Log_err ("Listen Fail:%s", Strerror (errno));
        return 1;

        } log_info ("Listening on%s", Szsocketpath);
        struct Sockaddr_un stclientaddr;
        socklen_t Nclientaddrlen = sizeof (STCLIENTADDR);

        memset (&stclientaddr, 0, sizeof (STCLIENTADDR));
        int iclientfd = Accept (iFd, (struct sockaddr *) &stclientaddr, &nclientaddrlen); if (iclientfd < 0) {Log_err ("Accept Fail:%s", Strerror (errno));
        return 1;

        } log_info ("Connected:client Addr%s", Stclientaddr.sun_path);

        pid_t pid = fork ();
            if (PID = = 0)//parent process {Close (ICLIENTFD);
        Continue
        else if (PID < 0) {Log_err ("Fork Fail:%s", Strerror (errno));

        } char acbuf[4096] = {0};

        int icnt = 0; 
        while ((icnt = Read (ICLIENTFD, acbuf, sizeof (ACBUF))) {Log_info ("read%d bytes:[%s]", icnt, Acbuf);

        } log_info ("Disconnected:client Addr%s", Stclientaddr.sun_path);
    return 0; }
}

The

Client code is as follows: Create a UNIX socket and connect the listening sockets under/tmp/test.sock, read the data from standard input and send it to the server side through a socket

/****************************************************************************** * File name: Client.cpp * File Description: UNIX domain socket Test * Created Date: 2015-04-02 * Author: Casheywen ******************************************************************
/#include <iostream> using namespace std; #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #include <signal.h> #define LOG_ERR (FMT, args ...) fprintf (stderr, "pid:%d|") FMT "\ n", Getpid (), # #args) #define LOG_INFO (FMT, args ...) fprintf (stdout, "pid:%d|"
    FMT "\ n", Getpid (), # #args) void Sigpipehandler (int isigno) {Log_err ("Sigpipe received");
Exit (1);
    BOOL Connectunixsocket (const char *pszpath, int iFd) {struct Sockaddr_un staddr;

    memset (&staddr, 0, sizeof (STADDR));
    staddr.sun_family = Af_unix;

    strncpy (Staddr.sun_path, Pszpath, sizeof (Staddr.sun_path));
    int iRet = connect (iFd, (struct sockaddr *) &staddr, sizeof (STADDR));
if (IRet < 0)    {Log_err ("Connect Fail:%s", Strerror (errno));
    return false;
return true;

    int main () {const char szsocketpath[] = "/tmp/test.sock";
    int iFd = socket (Af_unix, sock_stream, 0);
        if (IFd < 0) {Log_err ("Create Socket Fail:%s", Strerror (errno));
    return 1; } if (!
        Connectunixsocket (Szsocketpath, iFd)) {Log_err ("Connectunixsocket Fail");
    return 1;

    } log_info ("Connect Success");  if (Sig_err = = Signal (sigpipe, Sigpipehandler))//Call the Write function when the connection is interrupted receives the sigpipe signal {log_err ("Signal Fail:%s",
        Strerror (errno));
    return 1;
    } Char szcontent[2048];

    ssize_t nwrite = 0;

        while (CIN >> szcontent) {nwrite = write (IFd, szcontent, strlen (szcontent));
            if (Nwrite < 0) {Log_err ("Write Fail:%s", Strerror (errno));
        return 1;
} return 0;
 }

Program test results:

Server Side

$./testunixsocket 
pid:10013| Listening On/tmp/test.sock
pid:10013| Connected:client Addr 
pid:10037| Listening On/tmp/test.sock
pid:10013| Read BYTES:[ALSDKFJLASJDF]
pid:10013| Read BYTES:[ASDFLJASLDFALSKDJF]
pid:10013| Read BYTES:[ALSDJKFASLDFJALSDKFJ]
pid:10013| Read BYTES:[ASDASDFASDFASDFASDASDFLKJSADF]
^c

Client Side

$./client 
pid:10036| Connect Success
alsdkfjlasjdf
asdfljasldfalskdjf
alsdjkfasldfjalsdkfj
ASDASDFASDFASDFASDASDFLKJSADF
ASDFASDFFSD
pid:10036| Sigpipe received          ---server-side exit after the FD write, received Sigpipe

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.