寒假学习 第24天 (linux 高级编程) 笔记总结
一、基于socket文件的IPC
两种模型:
对等模型
C/S模型
1. 对等模型
绑定
(1) 建立socker内核对象 socket函数
int socket(int domain, 地址族类型 AF_UNIX AF_INET
int type, //指定数据存放的数据格式 流SOCK_STREAM(数据之间没有边界) / 报文SOCK_DGRAM(数据之间有边界)
int protocol); //指定协议,建议为0
(2) 把socket绑定在一个地址上(这个地址可以是文件,网络设备) URL(Uniform Resoure Locator)
协议: //路径/文件 例: file://test/1.c
struct sockaddr_in // 用internet地址
struct sockaddr_un // unix 本地文件
bind函数绑定地址
int bind(int sockfd,
struct sockaddr *my_addr, //绑定的地址 struct sockaddr 是为了通用,用后面一个参数addrlen地址的长度来判断是socket_un函数socket_in等
socklen_t addrlen); //地址的长度
(3) 接收 / 发送数据
read / write send / recv sendto / recvfrom
(4) 关闭socket
连接
(1)建立socket
(2)连接到目标 connect函数 (可选,如果不写就一定只能用sendto / recvfrom)
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
(3)发送/接收数据
(4) 关闭
例子:两个程序之间通信
绑定
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <string.h>
#include <linux/un.h>
#include <signal.h>
void handle(int s)
{
unlink("my.socket"); //删除socket文件
exit(1);
}
int main(int argc, const char *argv[])
{
signal(SIGINT,handle);
int fd;
int r;
char buf[100];
fd=socket(AF_UNIX,SOCK_DGRAM,0); //建立socket
if(fd==-1) printf("socket error:%m\n"),exit(-1);
struct sockaddr_un addr={0}; //构造本地文件地址
addr.sun_family=AF_UNIX;
memcpy(addr.sun_path,"my.socket",strlen("my.socket"));
bind(fd,&addr,sizeof(addr));//把socket绑定在地址上
if(r==-1) printf("bind error:%m\n"),exit(-1);
while(1)
{
bzero(buf,sizeof(buf));
r=read(fd,buf,sizeof(buf)); //接收数据
buf[r]=0;
printf("%s\n",buf);
}
close(fd); //关闭
unlink("my.socket"); //删除socket文件
return 0;
}
连接
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <string.h>
#include <linux/un.h>
int main(int argc, const char *argv[])
{
int fd;
int r;
char buf[100];
fd=socket(AF_UNIX,SOCK_DGRAM,0); //建立socket
if(fd==-1) printf("socket error:%m\n"),exit(-1);
struct sockaddr_un addr={0}; //构造本地文件地址
addr.sun_family=AF_UNIX;
memcpy(addr.sun_path,"my.socket",strlen("my.socket"));
r=connect(fd,(struct sockaddr*)&addr,sizeof(addr));//连接
if(r==-1) printf("connect error:%m\n"),exit(-1);
write(fd,"hello!",strlen("hello!"));
close(fd); //关闭
return 0;
}
每运行第二个程序,第一个程序就会输出“hello!”
例子2:网络通信
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <string.h>
#include <signal.h>
//#include <linux/un.h>
#include <netinet/in.h> //sockaddr_int结构体
#include <arpa/inet.h> //提供ip地址转化为整数等工具
void handle(int s)
{
unlink("my.socket"); //删除socket文件
exit(1);
}
int main(int argc, const char *argv[])
{
signal(SIGINT,handle);
int fd;
int r;
char buf[100];
fd=socket(AF_INET,SOCK_DGRAM,0); //建立socket
if(fd==-1) printf("socket error:%m\n"),exit(-1);
struct sockaddr_in addr={0}; //构造本地文件地址
addr.sin_family=AF_INET;
addr.sin_port=htons(3333); //host to network(long short)把主机字节序改成为了字节序号
addr.sin_addr.s_addr=inet_addr("192.168.1.103");
bind(fd,&addr,sizeof(addr));//把socket绑定在地址上
if(r==-1) printf("bind error:%m\n"),exit(-1);
while(1)
{
bzero(buf,sizeof(buf));
r=read(fd,buf,sizeof(buf)); //接收数据
buf[r]=0;
printf("%s\n",buf);
}
close(fd); //关闭
unlink("my.socket"); //删除socket文件
return 0;
}
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc, const char *argv[])
{
int fd;
int r;
char buf[100];
fd=socket(AF_INET,SOCK_DGRAM,0); //建立socket
if(fd==-1) printf("socket error:%m\n"),exit(-1);
struct sockaddr_in addr={0}; //构造本地文件地址
addr.sin_family=AF_INET;
addr.sin_port=htons(3333);
addr.sin_addr.s_addr=inet_addr("192.168.1.103");
r=connect(fd,(struct sockaddr*)&addr,sizeof(addr));//连接
if(r==-1) printf("connect error:%m\n"),exit(-1);
write(fd,"hello!",strlen("hello!"));
close(fd); //关闭
return 0;
}
同上面的例子一样,每运行第二个程序,第一个程序就会输出“hello!”