Article count:1382 Read by:1966155

Account Entry

Linux network application development---process communication IPC summary

Latest update time:2023-11-03
    Reads:
Click on the blue " Linux " in the upper left corner and select " Set as Star "


1. Brief description of the process:

Process is the concept of the operating system. Whenever we execute a program, a process is created for the operating system. In this process, resources are allocated and released. A process can be thought of as an execution of a program.

1) Process structure under Linux

The next process of Linux has three parts of data in the memory, namely "code segment", "stack segment" and "data segment". In fact, those who have studied assembly language must know that general CPUs have the above three segment registers to facilitate the operation of the operating system.

These three parts are also necessary parts to form a complete execution sequence. Therefore, between different processes, due to the management of virtual memory addresses in the Linux system, these three segments also exist independently, so the processes cannot access data from each other and need to communicate with each other through special methods provided by the system.

2) Methods of process communication under Linux:

Process user spaces are independent of each other and generally cannot access each other. But in many cases, processes need to communicate with each other to complete a certain function of the system. Processes coordinate their behavior by communicating with the kernel and other processes.

The more commonly used IPC communication methods are:

Pipes (named and unnamed), signals, semaphores, shared memory, message queues and socket communication.


3) Process communication usage scenarios:

(1) Data transmission: data transmission between processes;

(2) Notification event: A process sends a message to another process or a group of processes to notify the occurrence of a certain event (for example, the parent process needs to be notified when the child process terminates);

(3) Resource sharing: Multiple processes share resources, which requires the kernel to provide a synchronization mutual exclusion mechanism;

(4) Process control: A process needs to control the execution of another process (such as a Debug process). At this time, the control process needs to intercept all traps, exceptions, states, etc. of the other process.


2. Process communication method:

1. Named Pipes and Unnamed Pipes

a. Unnamed pipe (communication between parent and child processes, sibling processes):

---Features:

(1) Half-duplex. Data can only be transmitted in one direction at the same time;

(2) Data is written from one end of the pipe and read from the other end;

(3) Data written to the pipeline follows first-in, first-out;

(4) Pipes are not ordinary files, do not belong to a certain file system, and only exist in memory;

(5) Unnamed pipes can only be used between processes with common ancestors (parent-child processes, sibling processes, etc.).

---Steps:

(1) Create: The pipe function is used to create an unnamed pipe

(2) Operation: read; write

(3) Close the operation port: close

Example program:

		#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(void)
{
char buf[32] = {0};
pid_t pid;

// 数量为 2 个:一个读端, 一个写端,
int fd[2] = {-1};
// 创建无名管道
pipe(fd);
printf("fd[0] is %d\n", fd[0]);
printf("fd[2] is %d\n", fd[1]);

// 创建进程
pid = fork();
if (pid < 0)
{
printf("error\n");
}
if (pid > 0)
{
int status;
close(fd[0]);
write(fd[1], "hello", 5);
close(fd[1]);
wait(&status);
exit(0);
}
if (pid == 0)
{
close(fd[1]);
read(fd[0], buf, 32);
printf("buf is %s\n", buf);
close(fd[0]);
exit(0);
}
return 0;
}

b. Named pipes (allows communication between unrelated processes).

----Features:

(1) It allows two unrelated processes to communicate with each other

(2) The pipe can be indicated by a pathname and is visible in the file system. After the pipeline is established, the two processes can read and write it as an ordinary file, which is very convenient to use.

(3) FIFO strictly follows the first-in-first-out principle. Reading from pipes and FIFO always returns data from the beginning, and writing to them adds data to the end. Named pipes do not support file positioning operations such as Iseek().

---Steps:

(1) Create a famous pipe file: mkfifo is both a command and a function; mknod can also create a pipe file;

(2) Open a famous pipe: open;

(3) Read/write: read/write

(4) close: close

Example program:

		(1)named_pipe_write.c:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
int ret;
char buf[32] = {0};
int fd;
if (argc < 2)
{
printf("Usage:%s <fifo name> \n", argv[0]);
return -1;
}
if (access(argv[1], F_OK) == -1)
{
///创建有名管道文件
ret = mkfifo(argv[1], 0666);
if (ret == -1)
{
printf("mkfifo is error \n");
return -2;
}
printf("mkfifo is ok \n");
}
///打开有名管道文件
fd = open(argv[1], O_WRONLY);
while (1)
{
sleep(1);
write(fd, "hello", 5);
}
close(fd);
return 0;
}


(2) named_pipe_read.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main(int argc, char *argv[])
{
char buf[32] = {0};
int fd;
if (argc < 2)
{
printf("Usage:%s <fifo name> \n", argv[0]);
return -1;
}
///打开有名管道,write已经创建的文件;
fd = open(argv[1], O_RDONLY);
while (1)
{
sleep(1);
read(fd, buf, 32);
printf("buf is %s\n", buf);
memset(buf, 0, sizeof(buf));
}
close(fd);
return 0;
}

2. Signal amount

1) Concepts and principles:

A semaphore is a counter used to control access to shared resources. Every time a process accesses a shared resource, it must first obtain a semaphore. If the value of the semaphore is greater than 0,

Then the process can continue to access, otherwise the process needs to wait. After the access is completed, the process will release the semaphore and increase its value by 1 to facilitate access by other processes;

2) Related functions:

The Linux system provides the following functions to operate on semaphore values, and the included header file is sys/sem.h.

--semget function: Create a new semaphore or obtain the key of an existing semaphore

--semop function: Change the semaphore and perform p or v operations

--semctl function: used to directly control semaphore information

--Delete semaphore: ipcrm -s id

3) Example program:

---增加信号量的值例子(sempore_add.c ):		//=============================sempore_add.c==========================
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>

#define KEY 1234

union semun {
int val;
struct semid_ds *buf;
ushort *array;
};

int main()
{
int semid = semget(KEY, 1, IPC_CREAT | 0666);
if (semid < 0) {
perror("semget error");
return 1;
}

union semun arg;
arg.val = 1;
if (semctl(semid, 0, SETVAL, arg) < 0) {
perror("semctl error");
return 1;
}

struct sembuf buf;
buf.sem_num = 0;
buf.sem_op = 1;
buf.sem_flg = SEM_UNDO;

if (semop(semid, &buf, 1) < 0) {
perror("semop error");
return 1;
}

printf("Semaphore value: %d\n", semctl(semid, 0, GETVAL, arg));
return 0;
}

---Example of reducing semaphore value (sempore_sub.c):

			//=============================sempore_sub.c==========================

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>

#define KEY 1234

union semun {
int val;
struct semid_ds *buf;
ushort *array;
};

int main()
{
int semid = semget(KEY, 1, IPC_CREAT | 0666);
if (semid < 0) {
perror("semget error");
return 1;
}

union semun arg;
arg.val = 1;
if (semctl(semid, 0, SETVAL, arg) < 0) {
perror("semctl error");
return 1;
}

struct sembuf buf;
buf.sem_num = 0;
buf.sem_op = -1;
buf.sem_flg = SEM_UNDO;

if (semop(semid, &buf, 1) < 0) {
perror("semop error");
return 1;
}

printf("Semaphore value: %d\n", semctl(semid, 0, GETVAL, arg));


////销毁信号量
if (semctl(semid, 0, IPC_RMID, 0) < 0) {
perror("semctl error");
return 1;
}

printf("Semaphore destroyed\n");
return 0;
}



3. Signal

(1) Signal concepts and principles:

Signals are an asynchronous communication method. When a process receives a signal, it interrupts the current execution and instead executes the signal processing function associated with the signal. More similar to soft interrupt. But signals and interrupts are different. The response and processing of interrupts occur in kernel space, while the response of signals occurs in kernel space, and the execution of signal handlers occurs in user space.

Linux provides many signals, such as SIGINT, SIGTERM, SIGKILL, etc. You can view all signals and corresponding numbers in the Linux system Shell: kill -l

(2) Main functions:

a. void (*signal(int sig,void (*func)(int)))(int);

Description: Bind the callback function after receiving a certain signal. The first parameter is the signal, and the second parameter is the user's own processing function pointer for the signal. The return value is a pointer to the previous signal handler. Example: int ret = signal(SIGSTOP, sig_handle);

b. int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);

Note: Since signal is not robust enough, it is recommended to use the sigaction function. The sigaction function reimplements the signal function.

c. int kill(pid_t pid,int sig);

Description: The kill function sends a signal to the process whose process number is pid, and the signal value is sig. When pid is 0, the signal sig is sent to all processes in the current system.

There are four situations for the pid parameter of kill:

---pid>0, then send signal sig to the process with process number pid

---pid=0, then send the signal sig to all processes in the group to which the current process belongs.

---pid=-1, then send the signal sig to all processes except process No. 1 and the current process.

---pid<-1, then send the signal sig to all processes belonging to the process group pid

Example: End the parent process kill(getppid(), SIGKILL);

d. int raise(int sig);

Description: Bootstrap a signal sig into the current process, that is, send a signal to the current process. Equivalent to kill(getpid(),sig);

e. unsigned int alarm(unsigned int seconds);

Description: Used to set the signal SIGALRM to be sent to the current process after the number of seconds specified by the parameter seconds. If the parameter seconds is 0, the previously set alarm will be canceled and the remaining time will be returned.

f. int sigqueue(pid_t pid, int sig, const union sigval value);

Description: Used to send a specific signal to the specified process and can pass an additional data value. It provides richer functions than the kill function and can be used for advanced communication between processes.


(3) Example program:

			-----------------signal_receiver.c ------------------------------
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <unistd.h>

void signal_Handle(int sig, siginfo_t* info, void* ucontext)
{
printf("handler : sig = %d\n", sig);
printf("handler : info->si_signo = %d\n", info->si_signo);
printf("handler : info->si_code = %d\n", info->si_code);
printf("handler : info->si_pid = %d\n", info->si_pid);
printf("handler : info->si_value = %d\n", info->si_value.sival_int);
}

int main(int argc, char** argv)
{
printf("pid :%d\n", getpid());

struct sigaction act = {0};

act.sa_sigaction = signal_Handle;
act.sa_flags = SA_RESTART | SA_SIGINFO;

/* 添加信号屏蔽字 */
/* 下面信号在信号处理程序执行时会被暂时阻塞 */
sigaddset(&act.sa_mask, 40);
sigaddset(&act.sa_mask, SIGINT);

/* 设置信号的处理行为,设置后40和SIGINT信号将由act里面的信号处理函数处理 */
sigaction(40, &act, NULL);
sigaction(SIGINT, &act, NULL);

while(1)
{
sleep(1);
}

return 0;
}
			-----------------signal_sender.c ------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>


int main(int argc, char** argv)
{
pid_t pid = atoi(argv[1]);

union sigval sv = {123456};

//向指定pid发送信号;
sigqueue(pid, 40, sv);

raise(SIGINT);

return 0;
}

4.Message queue

(1) Concepts and principles:

Message queue is a method of inter-process communication that allows one process to send messages to another process. It is an asynchronous communication method. The sender can continue execution after sending the message without waiting for the receiver's response.

The principle is shown in the figure below:


(2) Features:

---The message queue is a linked list of messages, stored in memory, and the kernel maintains the message queue;

---Messages in the message queue have types and formats;

---The message queue can implement random query of messages, which does not necessarily follow the first-in, first-out order. Instead, each process can read according to a custom type;

---Same as the pipe, after reading the data, the corresponding data in the message queue will be deleted;

---Each pipeline has a message queue identifier, which is unique in the entire system;

---The message queue allows one or more processes to write or read data to it;

---The message queue will be deleted only when the kernel is restarted or manually deleted, otherwise it will always exist in the system.

(3) Related functions:

a. key_t ftok(const char *pathname, int proj_id);

Description: Obtain the system's unique Key value (IPC key value). There may be many message queues in the system. Through Key, the system's unique value, you can select the message queue you want to enter;

b. int msgget(key_t key, int msgflg);

Description: Create or open a new message queue. Even if the processes are different, if the key value is the same, then you can enter the same message queue and return the same message queue identifier.

c. View some Linux commands of the message queue:

ipcs -q: View the current message queue for inter-process communication

ipcrm -q queue number: delete the specified message queue;

d. int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

Description: Add new messages to the message queue;

e. ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

Description: Accept information from the specified message queue identifier, and delete the information from the message queue once the acceptance is successful.

f. int msgctl(int msqid, int cmd, struct msqid_ds *buf);

Description: Modify the message queue, modify properties or delete the message queue, etc.


(3) Example program:

			-----------------message_sender.c ------------------------------
#include<stdio.h>
#include<sys/msg.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
//定义消息
struct mess
{

long type;
char data[128];
};
int main()
{
key_t key;

///创建生成唯一的key;
if ((key = ftok("/home/tmp", 'a')) == -1) {
perror("ftok");
exit(1);
}


int msgid=msgget((key_t)key,IPC_CREAT|0600);
if(msgid==-1)
{
exit(0);
}
struct mess dt;
dt.type=1;
strcpy(dt.data,"hello1");

//1号消息内容hello1
msgsnd(msgid,(void*)&dt,128,0);//标志位0
}


-----------------message_reader.c ------------------------------
#include<stdio.h>
#include<sys/msg.h>
#include<stdlib.h>
#include<unistd.h>

struct mess
{

long type;
char data[128];
};
int main()
{
int msgid=msgget((key_t)1235,IPC_CREAT|0600);
if(msgid==-1)
{
exit(0);
}
struct mess dt;
msgrcv(msgid,(void*)&dt,128,1,0);
printf("%s",dt.data);

///删除队列
if (msgctl(msqid, IPC_RMID, NULL) == -1) {
perror("msgctl");
exit(1);
}
}

5. Shared memory

(1) Concept:

Shared memory is an efficient IPC mechanism and the fastest inter-process communication method. Many programs that pursue efficiency will choose it when communicating with each other; it allows multiple processes to share the same physical memory area, thereby avoiding the need for data Copying and process switching overhead.

The principle is shown in the figure below:


(2) Creation and release of shared memory:

---The establishment of shared memory roughly includes the following two processes:

a. Apply for shared memory space in physical memory;

b. Attach the applied shared memory to the address space, that is, establish a mapping relationship;

---The release of shared memory roughly includes the following two processes:

a. Disassociate the shared memory from the address space, that is, cancel the mapping relationship.

b. Release the shared memory space, that is, return the physical memory to the system.

(3) Related functions:

a.key_t ftok(const char *pathname, int proj_id);

Note: This returned key value can be passed to the shared memory parameter as the key that uniquely identifies the shared memory in struct ipc_perm;

b. int shmget(key_t key, size_t size, int shmflg);

Description: Creation of shared memory;

c. void *shmat(int shmid, const void *shmaddr, int shmflg)

Description: Connect shared memory to the process address space. The third parameter shmflg of the shmat function has the following three options:

SHM_RDONLY: Only read operations are performed after associating shared memory

SHM_RND: If shmaddr is not NULL, the associated address is automatically adjusted downward to an integer multiple of SHMLBA.

0: Default is read and write permissions

d. int shmctl(int shmid, int cmd, struct shmid_ds *buf);

Description: Control shared memory, cmd is as follows:

IPC_STAT: Get the current associated value of the shared memory. At this time, the parameter buf is used as an output parameter.

IPC_SET: On the premise that the process has sufficient permissions, set the current associated value of the shared memory to the value in the data structure pointed to by buf

IPC_RMID: Delete shared memory segment;

e. int shmdt(const void *shmaddr)

Description: Disassociate shared memory from process address space

(3) System commands related to memory coexistence:

---View shared memory command: ipcs -m

---Delete shared memory command: ipcrm -m

(4) Example program: shared memory data reading;

	  //shm_server.c
-----------------shm_server.c ------------------------------
#include <stdio.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>

#define PATHNAME "/home/IPC/shm/server.c" //路径名
#define PROJ_ID 0x6666 //整数标识符

int main()
{
key_t key = ftok(PATHNAME, PROJ_ID); //获取key值
if (key < 0){
perror("ftok");
return 1;
}

int shm = shmget(key, SIZE, IPC_CREAT | IPC_EXCL | 0666); //创建新的共享内存
if (shm < 0){
perror("shmget");
return 2;
}

printf("key: %x\n", key); //打印key值
printf("shm: %d\n", shm); //打印共享内存用户层id

char* mem = shmat(shm, NULL, 0); //关联共享内存

while (1)
{
//服务端不断读取共享内存当中的数据并输出
while (1)
{
printf("client# %s\n", mem);
sleep(1);
}

}

shmdt(mem); //共享内存去关联

shmctl(shm, IPC_RMID, NULL); //释放共享内存
return 0;
}


Client: Shared memory data writing;

	-----------------shm_client.c ------------------------------

#include <stdio.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>

#define PATHNAME "/home/IPC/shm/server.c" //路径名
#define PROJ_ID 0x6666 //整数标识符

int main()
{
key_t key = ftok(PATHNAME, PROJ_ID); //获取与server进程相同的key值
if (key < 0){
perror("ftok");
return 1;
}
int shm = shmget(key, SIZE, IPC_CREAT); //获取server进程创建的共享内存的用户层id
if (shm < 0){
perror("shmget");
return 2;
}

printf("key: %x\n", key); //打印key值
printf("shm: %d\n", shm); //打印共享内存用户层id

char* mem = shmat(shm, NULL, 0); //关联共享内存

int i = 0;
while (1)
{
//客户端不断向共享内存写入数据
int i = 0;
while (1)
{
mem[i] = 'A' + i;
i++;
mem[i] = '\0';
sleep(1);
}
}

shmdt(mem); //共享内存去关联
return 0;
}


6. Sockets

(1) Concepts and principles:

Sockets are a programming interface for network communication and a special IPC communication mechanism. They are generally divided into two roles: client and server. They can communicate between different processes on the local machine or across networks. Communication between different hosts can be one-to-many.

The process is as follows:


(2) Related functions:

a. int tcp_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

Description: The Create Socket function creates a Socket object and specifies the communication protocol and type (streaming or datagram). IPPROTO_TCP represents TCP protocol

b. int bind(int sock, struct sockaddr *addr, socklen_t addrlen); //Linux

Description: Bind address, use bind function to bind Socket to a specific IP address and port number.

c. listen;

Description: Set up monitoring and wait to receive client connection requests;

d. int accept(int sock, struct sockaddr *addr, socklen_t *addrlen);

Description: Accept the connection. For streaming Socket, use the accept function to accept the client's connection request and return a new Socket object for communication with the client. For datagram Socket, this step can be omitted.

e. int connect(int sock, struct sockaddr *serv_addr, socklen_t addrlen);

Description: Connect to the server with the specified IP and port

f. ssize_t send(int sockfd, const void *buf, size_t len, int flags);

或ssize_t write(int fd, const void *buf, size_t nbytes);

Description: Data sending;

g. ssize_t recv(int sockfd, void *buf, size_t len, int flags);

或 ssize_t read(int fd, void *buf, size_t nbytes);

Description: Data reception;

h. int close(int fd) ;

Description: Close the connection and use the close function to close the Socket connection.

(3) Example program:

Local socket communication server program:

		----------------local_socket_server.c ------------------------------
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>

#define QLEN 10
#define IPC_SOCKET_PATH "ipctest.socket"

int serv_listen(const char *name)
{
int fd, len, err, rval;
struct sockaddr_un un;

/* create a UNIX domain stream socket */
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
return(-1);
/* in case it already exists */
unlink(name);

/* fill in socket address structure */
memset(&un, 0, sizeof(un));
un.sun_family = AF_UNIX;
strcpy(un.sun_path, name);
len = offsetof(struct sockaddr_un, sun_path) + strlen(name);

/* bind the name to the descriptor */
if (bind(fd, (struct sockaddr *)&un, len) < 0) {
rval = -2;
goto errout;
}
if (listen(fd, QLEN) < 0) { /* tell kernel we're a server */
rval = -3;
goto errout;
}
return(fd);

errout:
err = errno;
close(fd);
errno = err;
return(rval);
}

int serv_accept(int listenfd, uid_t *uidptr)
{
int clifd, len, err, rval;
time_t staletime;
struct sockaddr_un un;
struct stat statbuf;

len = sizeof(un);
if ((clifd = accept(listenfd, (struct sockaddr *)&un, &len)) < 0)
return(-1); /* often errno=EINTR, if signal caught */

/* obtain the client's uid from its calling address */
len -= offsetof(struct sockaddr_un, sun_path); /* len of pathname */
un.sun_path[len] = 0; /* null terminate */

if (stat(un.sun_path, &statbuf) < 0) {
rval = -2;
goto errout;
}
if (S_ISSOCK(statbuf.st_mode) == 0) {
rval = -3; /* not a socket */
goto errout;
}
if (uidptr != NULL)
*uidptr = statbuf.st_uid; /* return uid of caller */
/* we're done with pathname now */
unlink(un.sun_path);
return(clifd);

errout:
err = errno;
close(clifd);
errno = err;
return(rval);
}

///////////////////////////main ////////////////////////////////
int main(void)
{
int lfd, cfd, n, i;
uid_t cuid;
char buf[1024];
lfd = serv_listen(IPC_SOCKET_PATH);

if (lfd < 0) {
switch (lfd) {
case -3:perror("listen"); break;
case -2:perror("bind"); break;
case -1:perror("socket"); break;
}
exit(-1);
}
cfd = serv_accept(lfd, &cuid);
if (cfd < 0) {
switch (cfd) {
case -3:perror("not a socket"); break;
case -2:perror("a bad filename"); break;
case -1:perror("accept"); break;
}
exit(-1);
}
while (1)
{
n = read(cfd, buf, 1024);

if (n == -1) {
if (errno == EINTR)
break;
}
else if (n == 0) {
printf("the other side has been closed.\n");
break;
}

////send back data to client
for (i = 0; i < n; i++)
{ buf[i] = toupper(buf[i]);
write(cfd, buf, n);
}
}

close(cfd);
close(lfd);
return 0;
}


Local socket communication client program:

----------------local_socket_client.c ------------------------------

			#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>

#define CLI_PATH "/var/tmp/" /* +5 for pid = 14 chars */
#define IPC_SOCKET_PATH "ipctest.socket"

/*
* Create a client endpoint and connect to a server.
* Returns fd if all OK, <0 on error.
*/

int cli_conn(const char *name)
{
int fd, len, err, rval;
struct sockaddr_un un;

/* create a UNIX domain stream socket */
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
return(-1);

/* fill socket address structure with our address */
memset(&un, 0, sizeof(un));
un.sun_family = AF_UNIX;
sprintf(un.sun_path, "%s%05d", CLI_PATH, getpid());
len = offsetof(struct sockaddr_un, sun_path) + strlen(un.sun_path);

/* in case it already exists */
unlink(un.sun_path);
if (bind(fd, (struct sockaddr *)&un, len) < 0) {
rval = -2;
goto errout;
}

/* fill socket address structure with server's address */
memset(&un, 0, sizeof(un));
un.sun_family = AF_UNIX;
strcpy(un.sun_path, name);
len = offsetof(struct sockaddr_un, sun_path) + strlen(name);
if (connect(fd, (struct sockaddr *)&un, len) < 0) {
rval = -4;
goto errout;
}
return(fd);
errout:
err = errno;
close(fd);
errno = err;
return(rval);
}

///////////////////////////main ////////////////////////////////
int main(void)
{
int fd, n;
char buf[1024];

fd = cli_conn(IPC_SOCKET_PATH);
if (fd < 0) {
switch (fd) {
case -4:perror("connect"); break;
case -3:perror("listen"); break;
case -2:perror("bind"); break;
case -1:perror("socket"); break;
}
exit(-1);
}
while (fgets(buf, sizeof(buf), stdin) != NULL) {
write(fd, buf, strlen(buf));
n = read(fd, buf, sizeof(buf));
write(STDOUT_FILENO, buf, n);
}
close(fd);
return 0;
}

Socket IPC communication on different hosts belongs to the topic of network communication and will not be discussed in detail here.

end



A mouthful of Linux


Follow and reply [ 1024 ] Massive Linux information will be given away

Collection of wonderful articles

Article recommendation

【Album】 ARM
【Album】 Fans Q&A
【Album】 All original works
Album Introduction to linux
Album Computer Network
Album Linux driver



Latest articles about

 
EEWorld WeChat Subscription

 
EEWorld WeChat Service Number

 
AutoDevelopers

About Us Customer Service Contact Information Datasheet Sitemap LatestNews

Room 1530, Zhongguancun MOOC Times Building,Block B, 18 Zhongguancun Street, Haidian District,Beijing, China Tel:(010)82350740 Postcode:100190

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号