1.概念
不同主机的进程间通信
2.网络通信
- 物理通路
- 逻辑通路
osi模型
3.网络参数
3.1 IP地址
- 是网络中主机的唯一标识,它由网络地址和主机号组成。网络地址是子网的唯一标识,类似于电话号码的区号;主机号是子网内每台主机的编号。在现在(IPv4)的网络中,IP地址是32bit的二进制数,采用大端字节序:
表示方法(点分十进制)
直接使用二进制数,不容易记忆,为了方便记忆,将32位二进制码划分为4个字节,每个字节转化成相应的十进制数,字节之间用“.”来分隔,这种表示方法,称之为“点分十进制表示法”。
3.2 子网掩码
获取IP地址中的网络地址和主机地址
3.3 网关
一个网络到另一个网络的关口
3.4 DNS(域名解析系统)
将www.baidu.com(域名,计算机名)转换成百度服务器的IP地址
4.socket函数
原型:#include <sys/types.h> /* See NOTES */ #include <sys/socket.h> int socket(int domain, int type, int protocol); 功能:创建通信的一段,返回文件描述符 参数: domain:域 -- 范围 type:类型 protocol:协议 传输层的协议:tcp协议、udp协议 0:默认为tcp协议 返回值: 成功返回这个套接字的文件描述符(fd) 失败返回-1 && error
域
选择通信的范围:ipv4(AF_INET)、ipv6(AF_INET6)、本地套接字(AF_UNIX, AF_LOCAL)
type类型
SOCK_STREAM(流式套接字):提供按顺序排列、可靠且双向的基于连接的字节,。还可能支持非带宽内的数据传输机制
SOCK_DGRAM(数据报套接字) :支持数据报(即无连接、不可靠且具有固定最大长度的报文)
TCP(transmission control protocol)协议
- 连接
- 可靠传输
- 字节流
特点
- 面向连接
- 提供可靠传输(无丢失,无丢序,无差错,无重复)
建立连接
- 三次握手
应用场合
- 对可靠性要求较高的场合
- qq、微信登陆时
UDP(User datagram Protocol)协议:
- 不可靠
- 无连接
- 数据报
特点:
- 不可靠传输
- 在数据发送时,不需要建立连接
应用场合
- 小数据,但是对速度要求较高(QQ、及时文本信息,语音,实时性要求较高场合)
- 广播、组播
- 无线网的传输
5.网络通信模式
c/s
- client:客户端
- server:服务器
- qq、微信
b/s
- browser:浏览器
- server:服务器
- 通用的浏览器
p2p
- peer to peer :点对点
6.基于tcp协议的c/s模型
tcp通信类似打电话
6.1 tcp客户端(角色--主动的一方)
socket //买了个电话
bind(可选)//买了sim卡
connect //开始拨打电话
write //通信
read
close //挂机
connect
原型:int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen); 功能:通过socket链接到指定的地址上 参数: sockfd:socket创建的的文件描述符 addr:标识网络中一个进程对应的地址 ip:确定一台主机 端口号:用来标识一个网络通信的进程 ip + 端口号 addrlen:说明第二个参数地址类型的大小 返回值: 成功返回0 失败返回-1 //不是通用的,不同的通信域(ipv4,ipv6...)都有自己独特的结构体 struct sockaddr *addr ipv4: struct sockaddr_in { sa_family_t sin_family; /* address family: AF_INET :ipv4*/ in_port_t sin_port; /* port in network byte order :端口号*/ struct in_addr sin_addr; /* internet address :ip地址*/ }; /* Internet address. */ struct in_addr { in_addr_t s_addr; /* address in network byte order */ };
端口号:16位的整型数据
0~1023 //1024 --- 知名端口号
//http --- 80
1024~50000 //特定端口号
50000~ //临时分配的端口号
发送 -- 转换 -- 网络字节序(大端)
接收 -- 根据主机的大小端转换
端口号: uint32_t htonl(uint32_t hostlong); uint16_t htons(uint16_t hostshort); uint32_t ntohl(uint32_t netlong); uint16_t ntohs(uint16_t netshort); h -- host to -- 到 n -- network l -- long s -- short
ip地址转换 in_addr_t inet_addr(const char *cp); cp:表示要用的ip地址的字符串(点分十进制) "192.168.0.160" 返回:网络字节序形式的ip地址的32位数值
#include "../head.h" int main(int argc, const char *argv[]) { int fd = 0; struct sockaddr_in seraddr; char tmpbuff[1024]; seraddr.sin_family = AF_INET; seraddr.sin_addr.s_addr = inet_addr("192.168.233.1"); seraddr.sin_port = htons(50000); fd = socket(AF_INET, SOCK_STREAM, 0); if(fd < 0) { perror("fail to socket"); return -1; } // printf("fd = %d\n", fd); connect(fd, (const struct sockaddr *)&seraddr, sizeof(seraddr)); while(1) { memset(tmpbuff, 0, sizeof(tmpbuff)); m_fgets(tmpbuff); if(strcmp(tmpbuff, ".quit") == 0) { break; } write(fd, tmpbuff, strlen(tmpbuff)); } close(fd); return 0; }
6.2 tcp服务器(角色--被动的一方)
socket //买了个电话
bind //买了sim卡
listen //监听--待机 等待打电话过来
accept //接听
read //通信
write
close //挂机
bind
原型: int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen); 功能: 给sockfd绑定一个地址信息(ip + port) 参数: sockfd:要操纵的socket addr:要绑定的地址信息 addrlen:地址对应的大小 返回值: 成功返回0 失败返回-1 struct sockaddr_in { sa_family_t sin_family; /* address family: AF_INET :ipv4*/ in_port_t sin_port; /* port in network byte order :端口号*/ struct in_addr sin_addr; /* internet address :ip地址*/ }; /* Internet address. */ struct in_addr { in_addr_t s_addr; /* address in network byte order */ };
listen
原型:int listen(int sockfd, int backlog); 功能:将sockfd对应的socket设置为监听套接字(负责看客户端有没有发送连接请求,有请求就放在等待队列) 参数: sockfd:socket的fd backlog:等待队列的长度 返回值: 成功返回0 失败返回-1
accept
原型:int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); 功能: 从监听的socket中提取请求,完成连接(三次握手) 参数: sockfd:监听的socket的fd addr:存放客户端的地址信息 addrlen:值结果参数 注意:必须初始化,初始化成addr对应(socklen_t)类型大小 返回值: 成功返回已连接的socket的fd //专门用于后面通信的 失败返回-1