Process Note 2: Communication between processes (Unix domain socket socket)

Source: Internet
Author: User
Tags bind sleep socket error sprintf strlen unix domain socket

The address data structure of the socket has different forms depending on the system and the network environment. In order for the different format addresses to be passed into the socket function, the address structure must be forced to be converted to:

struct sockaddr{
   sa_family_t sa_family;/* address family*/
   char        sa_data[];/* Variable-length address*/
   ...
};

The socket implementation is free to add additional members and to define the size of the Sa_data member. For example, in Linux, the structure is defined as follows

struct sockaddr{
   sa_family_t sa_family;   /* Address family*/
   char        sa_data[14];/* variable-length address*/
};

Where sa_family_t represents the communication domain of the socket. There are four main values:


Domain Describe
Af_inet IPV4 Internet domain
Af_inet6 IPV6 Internet domain
Af_unix UNIX domain
Af_unspec Not specified


The functions for creating sockets are as follows

#include <sys/socket.h>
int socket (int domain, int type, int protocol);/* return file (socket) descriptor successfully, error return-1

Where domain refers to the communication field, type refers to the type of socket, the following four types are mainly

Type Describe
Sock_dgram Fixed-length, non-connected unreliable message delivery
Sock_ram Datagram Interface for IP protocol
Sock_seqpacket Fixed-length, orderly, reliable connection-oriented message delivery
Sock_stream Sequential, reliable, bidirectional connection-oriented byte stream

The parameter protocol is typically zero, which means that the default protocol is selected by the given domain and socket type. When multiple protocols are supported for the same domain and socket type, you can use the protocol parameter to select a specific protocol.

An example of a multi-process communication using UNIX domain sockets (only on-premises) (the code is not easy to observe in two parts, the latter socket_unix.c to be part of it)

 /* domain_socket.h @Author: Duanjigang @2006-4-11 @Desp: Declaratin of methods used for unix-domain-socket communication */#ifndef _h_ #define _h_ #include <stdio.h> #include <unistd.h> #include <sys/un.h> #include <sys/
        socket.h> #define MSG_SIZE int init_send_socket (struct sockaddr_un * Addr,char * path) {int sockfd,len;
        Sockfd=socket (af_unix,sock_dgram,0);
        if (sockfd<0) {exit (1);
        } bzero (addr,sizeof (struct sockaddr_un));
        addr->sun_family=af_unix;
        strcpy (Addr->sun_path,path);
return SOCKFD; 
        } int Init_recv_socket (char * path) {int sockfd,len; 
        struct Sockaddr_un addr; 
        Sockfd=socket (af_unix,sock_dgram,0);
        if (sockfd<0) {return-1; 
        } bzero (&addr,sizeof (struct sockaddr_un)); 
        addr.sun_family = Af_unix;
        strcpy (Addr.sun_path, path);
        unlink (path); Len= strlen (Addr.sun_path) + sizeof (addr.sun_family);
         if (Bind (SOCKFD, (struct sockaddr *) &addr,len) <0) {return-1;

} return SOCKFD; 
      } int Receive_from_socket (int sockfd, char msg[]) {int n;
      memset (msg, 0, msg_size); 
      N=recvfrom (SOCKFD, MSG, msg_size, 0, NULL, NULL);
      if (n<=0) {return-1;
      } msg[n]=0;
return n; 
        } int Send_to_socket (int sockfd, char msg[], const struct Sockaddr_un * addr) {int len;
        Len = strlen (Addr->sun_path) +sizeof (addr->sun_family); 
        SendTo (SOCKFD, MSG, strlen (msg), 0, (struct sockaddr*) addr,len);
return 1; } #endif

/* MAIN.C @Author: duanjigang @ 2006-4-11 @Desp: Processes communicate with UNIX domain socket */#include "Domain_soc
  Ket.h "#define PATH"/home/useless "/* process communicates through the domain-Example: parent-child process, one send, one receive */int main (void) {int pid;
    /* The child process is used to send the message */if ((PID = fork ()) = = 0) {int fd, counter = 0;
    Char Send_buffer[msg_size];
    struct Sockaddr_un addr;
       if (fd = Init_send_socket (&addr, PATH)) > 0) while (1) {memset (send_buffer, 0, msg_size); /* Prevent counter out of bounds, so make a reset judgment */sprintf (Send_buffer, "message for%d Times", counter++ >= 10000? 1
       : Counter);
       Send_to_socket (FD, Send_buffer, &addr);
       printf ("Sender:%s\n", Send_buffer);
    Sleep (1);
      The}/* parent process is used to receive the message */else {int fd;
      Char Recv_buffer[msg_size];
       if (fd = Init_recv_socket (PATH)) > 0) while (1) {memset (recv_buffer, 0, msg_size); if (Receive_from_socket (FD, Recv_buffer)) {printf ("Receiver:%s\n", Recv_buffer);
  }
      }
  }
}

Examples of running results:

Sender:message for 1 times

sender:message for 2 times

receiver:message for 2 times

sender:message for 3 ti Mes

receiver:message for 3 times

sender:message for 4 times

receiver:message for 4 times

Sender:messag E for 5 times

receiver:message for 5 times


Socket_unix.c

Using UNIX domain sockets communication #include <stdio.h> #include <unistd.h> #include <sys/un.h> #include <sys/socket.h&

Gt
    #define MSG_MAX_SIZE 1024x768 #define PATH "a.socket"//Socket file int main () {int len;
    int socket_fd;

    struct Sockaddr_un addr;
    Bzero (&addr, sizeof (struct sockaddr_un));
    addr.sun_family = Af_unix; 
    strcpy (Addr.sun_path, path);
    
    Len = strlen (Addr.sun_path) +sizeof (addr.sun_family);
        if (!fork ())//child process internal code {int counter = 0;

        Char Send_buffer[msg_max_size]; 
        init send Socket SOCKET_FD = socket (Af_unix, SOCK_DGRAM, 0);
            if (socket_fd<0) {printf ("Client socket error!");
        return 0;
            } while (1)//loop sends data message {memset (send_buffer, 0, msg_max_size);
            
            sprintf (Send_buffer, "message for%d Times", counter++); The data information is sent to the addr specified socket file, so that the process can communicate sendto (SOCKET_FD, Send_buffer, STrlen (Send_buffer), 0, (struct sockaddr*) &addr, Len);
            printf ("sender:%s\n", Send_buffer);
        Sleep (1);

        }} else {char recv_buffer[msg_max_size];
        init recv Socket SOCKET_FD = socket (Af_unix, SOCK_DGRAM, 0);
            if (socket_fd<0) {printf ("Server Socket error!");
        return 0; } unlink (PATH);//prevents the socket file to be created already exists if (bind (SOCKET_FD, (struct sockaddr *) &addr, Len) <0)//Only
            The socket Path {printf ("bind error") will not be created on the hard disk after bind.
        return 0;

            } while (1)//loop receives data {memset (recv_buffer, 0, msg_max_size); The receive from socket reads data from the specified socket, where the socket is already bound to the file of the specified path Recvfrom (socket_fd, Recv_buffer, msg_max_size, 0,
            
            NULL, NULL);
        printf ("Receive Message:%s\n", Recv_buffer);
}} return 0;
 }


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.