socket通信编程
源代码:https://github.com/HanKin2015/Storage/tree/master/linux/socket
目标:学习jsonrpc+socket通信机制
1、创建父进程
include
获取进程id:pid_t getpid(void);
sleep() 秒级 usleep() 微秒级
2、创建子进程
fork函数调用一次,会返回两个函数值,对于父进程而言,返回的是子进程的PID(因为一个父进程可能有多个子进程,并且没有一个函数可以使父进程获取其所有的子进程ID),对于子进程返回值是0(这样就能区分父子进程,子进程是可以通过getppid来获取父进程的ID),如果进程创建失败,那么返回给父进程-1。
#include <iostream>
#include <cstdio>
#include <unistd.h>
using namespace std;
int main()
{
//for(int i = 0; i < 60; i++) {
// sleep(2);
// printf("pid = %d : %d\n", getpid(), i);
//}
int num = 3;
pid_t pid = 0;
pid = fork();
if (0 < pid) { //父进程得到的pid大于0,这段代码是父进程中执行的
for(int i = 0; i < 60; i++) {
sleep(2);
printf("parent pid = %d : %d\n", getpid(), i);
}
} else if(0 == pid) { //子进程得到的返回值是0,这段代码在子进程中执行
for(int i = 0; i < 60; i++) {
sleep(2);
printf("son pid = %d : %d\n", getpid(), i);
}
} else { //创建进程失败
//有两种情况会失败:
//1.进程数目达到OS的最大值
//2.进程创建时内存不够了。
printf("fork error!\n");
}
return 0;
}
通过ps -ef|grep a.out可以看见有两个进程存在。
3、socket通信
参考:https://blog.csdn.net/qq_31918961/article/details/80546537 "一切皆Socket!" 进程间通信(IPC) 网络层的“ip地址”可以唯一标识网络中的主机,而传输层的“协议+端口”可以唯一标识主机中的应用程序(进程)。这样利用三元组(ip地址,协议,端口)就可以标识网络的进程。
socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。我的理解就是Socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)。
domain:即协议域,又称为协议族(family)。常用的协议族有,AF_INET、AF_INET6、AF_LOCAL(或称AF_UNIX,Unix域socket)、AF_ROUTE等等。协议族决定了socket的地址类型,在通信中必须采用对应的地址,如AF_INET决定了要用ipv4地址(32位的)与端口号(16位的)的组合、AF_UNIX决定了要用一个绝对路径名作为地址。
type:指定socket类型。常用的socket类型有,SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等等。
protocol:故名思意,就是指定协议。常用的协议有,IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等,它们分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。
a) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。 b) Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
ipv4对应的是:
struct sockaddr_in {
sa_family_t sin_family; /* address family: AF_INET */
in_port_t sin_port; /* port in network byte order */
struct in_addr sin_addr; /* internet address */
};
/* Internet address. */
struct in_addr {
uint32_t s_addr; /* address in network byte order */
};
ipv6对应的是:
struct sockaddr_in6 {
sa_family_t sin6_family; /* AF_INET6 */
in_port_t sin6_port; /* port number */
uint32_t sin6_flowinfo; /* IPv6 flow information */
struct in6_addr sin6_addr; /* IPv6 address */
uint32_t sin6_scope_id; /* Scope ID (new in 2.4) */
};
struct in6_addr {
unsigned char s6_addr[16]; /* IPv6 address */
};
Unix域对应的是:
#define UNIX_PATH_MAX 108
struct sockaddr_un {
sa_family_t sun_family; /* AF_UNIX */
char sun_path[UNIX_PATH_MAX]; /* pathname */
};
sockaddr_in结构体:对应了网络中唯一的主机地址(ip地址sin_addr+协议sin_family+端口port)