网络编程
进程间的通信有:管道、信号、system V ipc对象通信号灯集
前面的通信都局限于本主机,而当跨主机通信时就操作不了。
其实TCP/IP协议族已经帮我们解决了这个问题,网络层的“ip地址”可以唯一标识网络中的主机,而传输层的“协议+端口”可以唯一标识主机中的应用程序(进程)。这样利用三元组(ip地址,协议,端口)就可以标识网络的进程了,网络中的进程通信就可以利用这个标志与其它进程进行交互。
1、相关关键字和历史
(1)套接字
所谓【套接字】(Socket),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲,套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议根进行交互的接口
(2)相关历史:
第一阶段:ARPAnet(阿帕网),是网络基础协议得雏形
第二阶段:第一份IP协议说明书
第三阶段:TCP/IP协议被制定
- 协议:两者之间得一种约定
(3)网络程序设计框架:C/S、B/S
<1>C/S:表示客户端/服务器设计框架
- 优点:支持本地缓存(能实现较好的效果)、应用层协议可以自己灵活制定
- 缺点:开发工作量较大、用户安全性较低
<2>B/S:表示浏览器/服务器设计框架
- 优点:开发工作量较小、用户安全性较高
- 缺点:不支持本地缓存、应用层协议必须遵守http协议
(4)网络协议分层模型:
OSI分层模型:理想的网络分层模型
- 应用层
- 表示层
- 会话层
- 传输层
- 网络层
- 数据链路层
- 物理层
TCP/IP分层模型:一种标准的网络分层模型
- 应用层:http协议、tftp协议、NFS协议。。。
- 传输层:TCP协议、UDP协议。。。
- 网络层:IP协议、ICMP协议。。。
- 物理接口层:以太网协议、ARP协议、RAPP。。。
eg:例如我们向另一台主机发送”还钱“
总结:
1.应用层:可以由用户自定义的协议,方便数据传输以及数据加密
2.传输层:提供端对端的数据传输
3.网络层:提供数据的路由
4.网络接口层:实现网络底层驱动
2、网络接口编程
Linux系统内核提供作为网络通信的接口
注:只有应用层是程序员能够自己定义的,下面三层的协议封装都是由内核完成的(但是又选择权力)
1、套接字分类
(1)流式套接字
数据以字节流(二进制流)的方式来进行传递,无大小限制,保证数据可靠,无丢失,顺序发送,主要用于TCP协议,一般情况下只要选择流式方式,那内核就会默认选择TCP传输层协议
(2)数据报套接字
主要通过数据报的方式发送,固定大小。不能保证数据可靠,可能丢失、乱序发送,主要用于UDP协议一般情况下只要选择数据报方式,那内核就会默认选择UDP传输层协议
(3)原始套接字
可以对较低层协议如IP、ICMP直接访问
3、相关接口函数
socket()—创建套接字
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type,int protocol);
参数:
domain:domain参数指定通信域;这将选择用于通信的协议族。
这些系列被定义在<sys/socket.h>中。
目前被Linux内核理解的格式包括:
AF_UNIX
AF_LOCAL
AF_INET
AF_AX25
AF_IPX
AF_APPLETALK
AF_X25
AF_INET6
AF_DECnet
AF_KEY ....
type:套接字具有指定的类型,该类型指定通信语义。目前定义的类型有:
SOCK_STREAM ---->流式套接字
SOCK_DGRAM ---->数据报套接字
SOCK_RAW ---->原始套接字
protocol:协议指定套接字使用的特定协议。在给定的协议族中,通常只存在“一个协议”来支持特定的套接字类型,在这种情况下,“协议默认为0”。
在多种协议这种情况下,特定的协议必须以这种方式指定。所使用的协议号特定于要在其中进行通信的“通信域”;参见getprotoent(3)了解如何将协议名称字符串映射到协议编号。
bind()—绑定套接字
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int bind(int sockfd, const str