之前说的用于进程间通信的几种方式:消息signal、管道pipe、消息队列msg、共享内存shm、信号量sem。都只适用于一台主机上的进程间通信,那么如何实现两台计算机之间的进程通信呢?所以,来了解一下异地进程通信。
1 异地进程通信
- 协议层为双方的主机通信进程分配“端口”和缓冲区,以便异地进程间的通信。
1.1TCP/IP协议
以下是OSI参考模型与TCP/IP参考模型的对应关系:
1.1.1 TCP/IP协议族
TCP/IP 协议组大体上分为三部分:
1.Internet 协议(IP)
2.传输控制协议(TCP)和用户数据报文协议(UDP)
3.处于TCP 和UDP 之上的一组协议专门开发的应用程序。它们包括:TELNET,文件传送协议(FTP),域名服务(DNS)和简单的邮件传送程序(SMTP)等许多协议。
应用层协议 - Telnet
- 文件传送协议(FTP和TFTP)
- 简单的文件传送协议(SMTP)
- 域名服务(DNS)等协议
2 网络编程基础
- socket标准被扩展成window socket和unix socket
- linux中的网络编程通过socket接口实现。
- Socket既是一种特殊的IO,它也是一种文件描述符。
- 一个完整的Socket 都有一个相关描述{协议,本地地址,本地端口,远程地址,远程端口};每一个Socket 有一个本地的唯一Socket 号,由操作系统分配。
2.1 SOCKET分类
流式套接字(SOCK_STREAM)
流式的套接字可以提供可靠的、面向连接的通讯流。它使用了TCP协议。TCP 保证了数据传输的正确性和顺序性。
数据报套接字(SOCK_DGRAM)
数据报套接字定义了一种无连接的服务,数据通过相互独立的报文进行传输,是无序的,并且不保证可靠,无差错。使用数据报协议UDP协议。
原始套接字。
原始套接字允许对低层协议如IP或ICMP直接访问,主要用于新的网络协议实现的测试等。2.2 编程流程
TCP
UDP
具体函数的用法,就自己man了。2.2.1 套接字地址结构
重点讲一下套接字地址结构:
#include < netinet/in.h> struct sockaddr { unsigned short sa_family; /* address族, AF_xxx */ char sa_data[14]; /* 14 bytes的协议地址 */ };
- sa_family的取值,一般来说,IPV4使用“AF_INET”
- sa_data包含了一些远程电脑的地址、端口和套接字的数目,里面的数据是杂溶在一起的。一般我们不用这个结构体,因为我们一般使用的地址都是IP+端口号。比如:IP192.168.159.2 port3306 。这样来记录地址。所以一般使用下面这个地址结构,而知数据类型是等效的,可以互相转换。
#include < netinet/in.h> struct sockaddr_in { short int sin_family; /* Internet地址族 */ unsigned short int sin_port; /* 端口号 */ struct in_addr sin_addr; /* Internet地址 */ unsigned char sin_zero[8]; /* 添0(和struct sockaddr一样大小)*/ };
2.2.2 字节序列转换
- 因为每一个机器内部对变量的字节存储顺序不同(有的系统是高位在前,底位在后,而有的系统是底位在前,高位在后 ),而网络传输的数据大家是一定要统一顺序的。所以对与内部字节表示顺序和网络字节顺序不同的机器,就一定要对数据进行转换。
- htons()——“Host to Network Short”