引言
在之前的笔记写的socket笔记,是通信方式中的一种扩展,前面笔记的socket都使用地址IP实现通信。实际上,socket可以使用在不需要IP的场合,即本地通信。(与进程间的通信(一)(匿名管道与有名管道)一样)
UNIX域套接字相比于前面的管道等提供的信息更多,比如:UNIX域可以等待对端的连接(与TCP类似),又可以实现帧同步(UDP类似)
本地域套接字的使用
字节流本地域套接字(不提供帧同步)
- 创建本地域套接字
- 定义本地域套接字结构体,并且绑定地址(有效路径)
- 等待连接(后面与TCP类似)
代码实现:
server.c:
#include <stdio.h>
#include "head4sock.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netdb.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#define LISTENQ 5
#define SIZE 100
int main(int argc, char **argv)
{
if(argc != 2)
{
fprintf(stderr,"Usage:%s <path>\n",argv[0]);
exit(1);
}
// 创建一个字节流本地域套接字(不提供帧同步) UNIX域套接字
int fd;
fd = Socket(AF_UNIX, SOCK_STREAM, 0);
//定义本地域套接字地址结构体
struct sockaddr_un local_address;
bzero(&local_address, sizeof local_address);
local_address.sun_family = AF_LOCAL;
memcpy(local_address.sun_path, argv[1], strlen(argv[1]));
//传进有效路径,在该路径上创建本地域套接字文件
// 绑定地址
Bind(fd,(struct sockaddr *)&local_address, sizeof(local_address));
Listen(fd, LISTENQ);
int connfd;
struct sockaddr_un peer_address;
socklen_t len = sizeof(peer_address);
bzero(&peer_address, len);
connfd = Accept(fd,(struct sockaddr *)&peer_address,&len);
printf("new connection %d from %s.\n", connfd, peer_address.sun_path);
char buf[SIZE];
while(1)
{
bzero(buf, SIZE);
if(read(connfd, buf, SIZE) == 0)
break;
printf("from peer: %s", buf);
}
close(fd);
close(connfd);
exit(0);
}
client.c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netdb.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include "head4sock.h"
#define BUFFER_SIZE 1024
int main(int argc,char **argv)
{
if(argc != 2)
{
fprintf(stderr,"Usage:%s <path>\n",argv[0]);
exit(1);
}
int fd;
fd = Socket(AF_LOCAL,SOCK_STREAM,0);
struct sockaddr_un remote_address;
bzero(&remote_address, sizeof remote_address);
remote_address.sun_family = AF_LOCAL;
memcpy(remote_address.sun_path,argv[1],strlen(argv[1]));
Connect(fd,(struct sockaddr *)&remote_address,sizeof(remote_address));
char buffer[BUFFER_SIZE];
while(1)
{
bzero(buffer, BUFFER_SIZE);
if(fgets(buffer, BUFFER_SIZE, stdin) == NULL)
break;
write(fd, buffer, strlen(buffer));
}
close(fd);
exit(0);
}
代码运行结果:
数据报本地域套接字(提供帧同步)
- 创建一个数据报本地域套接字
- 定义本地域套接字结构体,并且绑定地址(有效路径)
- 等待连接(与上类似)
代码实现:
server.c:
//:server.c
#include <stdio.h>
#include "head4sock.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netdb.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#define LISTENQ 5
#define SIZE 100
int main(int argc, char **argv)
{
if(argc != 2)
{
fprintf(stderr,"Usage:%s <path>\n",argv[0]);
exit(1);
}
// 创建一个数据报本地域套接字(提供了帧同步)
int fd;
fd = Socket(AF_LOCAL, SOCK_DGRAM, 0);
struct sockaddr_un local_address;
bzero(&local_address, sizeof local_address);
local_address.sun_family = AF_LOCAL;
memcpy(local_address.sun_path, argv[1], strlen(argv[1]));
Bind(fd,(struct sockaddr *)&local_address,sizeof(local_address));
struct sockaddr_un peer_address;
socklen_t len = sizeof(peer_address);
bzero(&peer_address, len);
char buf[SIZE];
while(1)
{
bzero(buf, SIZE);
if(recvfrom(fd, buf, SIZE, 0, NULL, NULL) == 0)
break;
printf("from peer: %s", buf);
}
close(fd);
exit(0);
}
client.c :
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netdb.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include "head4sock.h"
#define BUFFER_SIZE 1024
int main(int argc,char **argv)
{
if(argc != 2)
{
fprintf(stderr,"Usage:%s <path>\n",argv[0]);
exit(1);
}
int fd;
fd = Socket(AF_LOCAL,SOCK_DGRAM, 0);
struct sockaddr_un remote_address;
socklen_t len = sizeof(remote_address);
bzero(&remote_address, len);
remote_address.sun_family = AF_LOCAL;
memcpy(remote_address.sun_path,argv[1],strlen(argv[1]));
char buffer[BUFFER_SIZE];
while(1)
{
bzero(buffer, BUFFER_SIZE);
if(fgets(buffer, BUFFER_SIZE, stdin) == NULL)
break;
sendto(fd, buffer, strlen(buffer), 0,
(struct sockaddr *)&remote_address, len);
}
close(fd);
exit(0);
}
代码运行结果:
总结多种进程通信使用频率:
- 共享内存,信号量:效率高
- 本地域套接字:提供类似TCP的连接服务,可以控制缓冲区大小,灵活性大
- 管道:效率低