Implement socket-based multi-process real-time communication in Linux

Source: Internet
Author: User
Implement socket-based multi-process real-time communication in Linux

Zhou Xin (jones_zhou@yahoo.com.cn ),
Software Engineer

Introduction:Socket is the most widely used inter-process communication mechanism in Linux. However, it cannot be directly used for real-time communication between multiple processes. This paper proposes a socket-based multi-process communication implementation method, and provides the implementation and description of the sample program.

Label of this article:Linux and socket are implemented based on,
Multi-process real-time communication

Mark this article!

Release date:March 01, 2005
Level:Elementary
Access:8722 views
Comment:1 (View | Add comment-Log On)

Average score (21 scores)
Score for this article

Socket is the most widely used inter-process communication mechanism in Linux, different from other Linux communication mechanisms, it can be used for communication between processes in a single machine, but also between processes between different machines. However, because the socket itself does not support concurrent waiting and timeout processing, it cannot directly use multi-process mutual real-time communication.

This article proposes a socket-based multi-process communication implementation method. The principle is to establish a process dedicated to serve as a communication server to transit communication between processes. It first starts a listening socket to monitor connection requirements, and adds its description (descriptor) number to a previously defined fd_set collection, the fd_set set is used to store the description numbers of the listening socket and the communication socket generated later. Server uses System Call select to check whether any data arrives at any socket in the Set in real time. If any data arrives at listening
Socket, this must be a connection request initiated by the client. Therefore, a new communication socket is generated to connect to the client, and the generated socket description is added to the fd_set collection, record the Client ID and the corresponding socket description in the ID registration form. If data arrives at a communication socket, it must be a Communication Request initiated by a client. Read the data and retrieve the ID of the receiver client. In the ID registration form, find the corresponding socket description number, transmit data to the receiving client through the corresponding socket.

Other processes act as clients ). The client first establishes a communication socket to connect to the server, and then sends and receives messages through the communication socket.

The following describes the specific program implementation and description,

First, the server program is provided. Here we assume there are two clients for real-time communication. clienta sends 1 character to clientb and 2 character to clienta.

#include  <sys/types.h>#include <sys/socket.h>#include <stdio.h>#include <sys/un.h>#include <sys/time.h>#include <sys/ioctl.h>#include <unistd.h>#include <netinet/in.h>int main(){    int        rcd ;    struct sockaddr_un  server_sockaddr ;    int        backlog ;    ushort        ci ;    int        watch_fd_list[3] ;    fd_set        catch_fd_set ;    fd_set        watchset ;    int    new_cli_fd ;    int   maxfd;    int    socklen ,server_len;    struct sockaddr_un  cli_sockaddr ;    struct    {        char  module_id ;  /* Module ID    */        int  cli_sock_fd ;  /* Socket ID    */    } cli_info_t[2] ;    for (ci=0; ci<=1; ci++)        cli_info_t[ci].cli_sock_fd=-1;    for (ci=0; ci<=2; ci++)        watch_fd_list[ci]=-1;    int server_sockfd,client_sockfd;    server_sockfd = socket( AF_UNIX, SOCK_STREAM, 0 ) ;    server_sockaddr.sun_family = AF_UNIX ;    strcpy( server_sockaddr.sun_path, "server_socket" ) ;    server_len=sizeof(server_sockaddr);    rcd = bind( server_sockfd, ( struct sockaddr * )&server_sockaddr, server_len ) ;    backlog = 5 ;    rcd = listen( server_sockfd, backlog ) ;    printf("SERVER::Server is  waitting on socket=%d \n",server_sockfd);    watch_fd_list[0]=server_sockfd;    FD_ZERO( &watchset ) ;    FD_SET( server_sockfd, &watchset ) ;    maxfd=watch_fd_list[0];

In the above program, the server generates the listening socket (server_sockfd), initializes the socket monitoring set (watchset), and puts the listening socket into the socket monitoring set.

    while (1)    {        char ch;        int fd;        int nread;        catch_fd_set=watchset;        rcd = select( maxfd+1, &catch_fd_set, NULL, NULL, (struct timeval *)0 ) ;

In the above program, the server uses the system call function select to check whether data has arrived in any socket in the socket monitoring set in real time.

        if ( rcd < 0 )        {            printf("SERVER::Server 5 \n");            exit(1);        }        if ( FD_ISSET( server_sockfd, &catch_fd_set ) )        {            socklen = sizeof( cli_sockaddr ) ;            new_cli_fd = accept( server_sockfd, ( struct sockaddr * )                                 &( cli_sockaddr ), &socklen ) ;            printf(" SERVER::open communication with  Client %s on socket %d\n",                   cli_sockaddr.sun_path,new_cli_fd);            for (ci=1; ci<=2; ci++)            {                if(watch_fd_list[ci] != -1) continue;                else                {                    watch_fd_list[ci] = new_cli_fd;                    break;                }            }            FD_SET(new_cli_fd , &watchset ) ;            if ( maxfd < new_cli_fd )            {                maxfd = new_cli_fd ;            }            for ( ci=0; ci<=1; ci++)            {                if(cli_info_t[ci].cli_sock_fd == -1)                {                    cli_info_t[ci].module_id=cli_sockaddr.sun_path[0];                    cli_info_t[ci].cli_sock_fd=new_cli_fd;                    break;                }            }            continue;        }

In the preceding program, the server uses the system call function fd_isset to check whether a client connection request has arrived at the listening socket. If the returned value is greater than 0, the server generates a new communication socket (new_cli_fd) connect to the client. Place the new communication socket into the socket monitoring set (fd_set ). Save the client information (ID and socket description) in the Registry cli_info_t.

        for ( ci = 1; ci<=2 ; ci++ )        {            int      dst_fd = -1 ;            char      dst_module_id;            char       src_module_id;            int    i;            if (watch_fd_list[ ci ]==-1) continue;            if ( !FD_ISSET( watch_fd_list[ ci ], &catch_fd_set ) )            {                continue ;            }            ioctl(watch_fd_list[ ci ],FIONREAD,&nread);            if (nread==0)            {                continue;            }            read( watch_fd_list[ ci ], &dst_module_id, 1 ) ;            for (i=0; i<=1; i++)            {                if(cli_info_t[i].module_id == dst_module_id)                    dst_fd=  cli_info_t[i].cli_sock_fd;                if(cli_info_t[i].cli_sock_fd==watch_fd_list[ ci ])                    src_module_id=  cli_info_t[i].module_id;            }            read( watch_fd_list[ ci ], &ch, 1 ) ;            printf("SERVER::char=%c to  Client %c on socket%d\n",ch, dst_module_id,dst_fd);            write(dst_fd,&src_module_id, 1 ) ;            write(dst_fd,&ch, 1 ) ;        }    }}

In the preceding program, if data reaches a communication socket, the server reads the data and obtains the ID of the receiver client. In the ID registration form, find the socket description number corresponding to the email receiving client. And transmit the data to the receiving client through the corresponding socket

Client client program

The clientb program only needs to change char dst_module_id = 'B'; To char dst_module_id = 'a'; char CH = '1'; To char CH = '2.

#include  <sys/types.h>#include <sys/socket.h>#include <stdio.h>#include <sys/un.h>#include <unistd.h>#include <netinet/in.h>#include <arpa/inet.h>int main(){    int client_sockfd;    int len;    struct sockaddr_un server_sockaddr,cli_sockaddr;    int result;    char dst_module_id='B';    char ch='1';    char src_module_id;    client_sockfd= socket(AF_UNIX,SOCK_STREAM,0);    cli_sockaddr.sun_family = AF_UNIX ;    strcpy( cli_sockaddr.sun_path, "A" ) ;    bind(client_sockfd,(struct sockaddr * )&cli_sockaddr, sizeof( cli_sockaddr ) ) ;    server_sockaddr.sun_family=AF_UNIX;    strcpy( server_sockaddr.sun_path, "server_socket" ) ;    len=sizeof(server_sockaddr);    result = connect(client_sockfd,( struct sockaddr * )&server_sockaddr,len);    if (result <0)    {        printf("ClientA::error on connecting \n");        exit(1);    }    printf("ClientA::succeed in connecting with server\n");    sleep(10);    write(client_sockfd,&dst_module_id,1);    write(client_sockfd,&ch,1);    read (client_sockfd,&src_module_id,1);    read (client_sockfd,&ch,1);    printf("ClientA::char from  Client %c =%c\n", src_module_id,ch);    close (client_sockfd);}

The following is the execution result of the sample program.

[root@zhou test]# ./server &[3] 4301[root@zhou test]# SERVER::Server is  waitting on socket=3./clientA & ./clientB &[4] 4302[5] 4303ClientA::succeed in connecting with server SERVER::open communication with  Client A on socket 4[root@zhou test]#  SERVER::open communication with  Client B on socket 5ClientB::succeed in connecting with serverSERVER::char=1 to  Client B on socket5ClientB::char from  Client A =1SERVER::char=2 to  Client A on socket4ClientA::char from  Client B =2

Download the program list: Server. C, clienta. c

About the author

Zhou Xin graduated from the computer department of Beijing University of Posts and Telecommunications and is now engaged in software development in Japan.
Jones_zhou@yahoo.com.cn can contact him.

Reprinted from http://www.ibm.com/developerworks/cn/linux/l-socket-ipc/index.html

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.