进程间通信的方式
1. Pipe fifo 实现最简单
2. mmap 非血缘关系进程间
3. 信号 开销小
4. domain 套接字,稳定性最好
使用本地套接字,实现一个本地服务器和多个客户端之间通信 类似 server 作为服务器,接收客户端的数据,保存每个客户端的fd,实现和客户端的双向通信。
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <strings.h>
#include <string.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <sys/un.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <ctype.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include "wrap.h"
#define MAXLINE 8192
#define SERV_PORT 8000
#define SERV_ADDR "serv.socket"
enum TYPE
{
START,
KEY,
USB
};
char from[2];
char to[2];
int type;
char str[3];
struct s_info {
struct sockaddr_un cliaddr;
int connfd;
};
struct s_id{
char name[4];
int fd;
};
struct s_id id[4] = {
{"A", -1},
{"B", -1},
{"C", -1},
{"D", -1},
};
void *do_work(void *arg)
{
#if 1
int n,i;
struct s_info *ts = (struct s_info*)arg;
char buf[MAXLINE];
char str[INET_ADDRSTRLEN];
while (1) {
#if 1
n = Read(ts->connfd, buf, MAXLINE);
if (n == 0) {
printf("the client %d closed...\n", ts->connfd);
break;
}
printf(" n = %d, client bind filename %s\n", n, ts->cliaddr.sun_path);
#if 1
from[0] = buf[0];
from[1] = '\0';
to[0] = buf[1];
to[1] = '\0';
type = buf[2]-'0';
printf("from = %s \n", from);
printf("to = %s \n", to);
printf("type = %d\n", type);
if(strcmp(to, "s") == 0){
if(type == START){
printf("start type = %d\n", type);
for(i=0;i<4;i++){
if (strcmp(from,id[i].name) == 0 ){
id[i].fd = ts->connfd;
printf("i = %d, fd = %d \n", i, ts->connfd);
}
}
}
else if(type == KEY){
int key = buf[3] - '0';
printf("key = %d \n", key);
}
else if(type == USB ){
}
}
#endif
for (i = 0; i < n; i++)
{
buf[i] = toupper(buf[i]);
}
Write(STDOUT_FILENO, buf, n);
Write(ts->connfd, buf, n);
#else
n = Read(ts->connfd, buf, MAXLINE);
if (n == 0) {
printf("the client %d closed...\n", ts->connfd);
break;
}
#endif
}
Close(ts->connfd);
#endif
return (void *)0;
}
int main(void)
{
int lfd, cfd, len, size, i;
struct sockaddr_un servaddr, cliaddr;
char buf[4096];
struct s_info ts[10];
pthread_t tid;
lfd = Socket(AF_UNIX, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sun_family = AF_UNIX;
strcpy(servaddr.sun_path,SERV_ADDR);
len = offsetof(struct sockaddr_un, sun_path) + strlen(servaddr.sun_path);
unlink(SERV_ADDR);
Bind(lfd, (struct sockaddr *)&servaddr, len);
Listen(lfd, 20);
printf("Accept ...\n");
while (1) {
len = sizeof(cliaddr);
cfd = Accept(lfd, (struct sockaddr *)&cliaddr, (socklen_t *)&len);
len -= offsetof(struct sockaddr_un, sun_path);
cliaddr.sun_path[len] = '\0';
ts[i].cliaddr = cliaddr;
ts[i].connfd = cfd;
pthread_create(&tid, NULL, do_work, (void*)&ts[i]);
pthread_detach(tid);
i++;
}
return 0;
}
client
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <strings.h>
#include <string.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <sys/un.h>
#include <stddef.h>
#include "wrap.h"
#define SERV_ADDR "serv.socket"
#define CLIE_ADDR "clie.socket"
int main(void)
{
int cfd, len;
struct sockaddr_un servaddr, cliaddr;
char buf[4096];
cfd = Socket(AF_UNIX, SOCK_STREAM, 0);
bzero(&cliaddr, sizeof(cliaddr));
cliaddr.sun_family = AF_UNIX;
strcpy(cliaddr.sun_path,CLIE_ADDR);
len = offsetof(struct sockaddr_un, sun_path) + strlen(cliaddr.sun_path);
unlink(CLIE_ADDR);
Bind(cfd, (struct sockaddr *)&cliaddr, len);
bzero(&servaddr, sizeof(servaddr));
servaddr.sun_family = AF_UNIX;
strcpy(servaddr.sun_path,SERV_ADDR);
len = offsetof(struct sockaddr_un, sun_path) + strlen(servaddr.sun_path);
Connect(cfd, (struct sockaddr *)&servaddr, len);
while (fgets(buf, sizeof(buf), stdin) != NULL) {
write(cfd, buf, strlen(buf));
len = read(cfd, buf, sizeof(buf));
write(STDOUT_FILENO, buf, len);
}
close(cfd);
return 0;
}
|