网络基础与socket编程
一、OSI七层模型与TCP / IP五层(或四层)模型
1.OSI七层模型:下--->上
物理层-->数据链路层-->网络层-->传输层-->会话层-->表示层-->应用层
2.TCP / IP 五层模型(下--->上):
1) 物理层(以太网协议):负责光 / 电信号的传递方式。比如:网线(双绞线)、同轴电缆、光纤、wifi等。物理层的能力决 定了最大传输速率、传输距离、抗干扰等。工作在物理层的集线器:实现数据转换和放大。
2)数据链路层(以太网协议):负责两个相邻设备之间的数据帧的传送和识别。比如:帧同步,冲突检测,数据差错校验。
早期典型的交换机工作在数据链路层。
3)网络层(IP协议):负责地址管理和路由选择。比如:IP协议中,通过IP协议标识一台主机,并通过路由表规划出两台之间最佳路径。路由器工作在网络层。
4)传输层(TCP UDP协议):负责两台主机上应用程序之间的数据传输。比如:TCP协议,确保数据可靠的从源主机发送到目标主机。
5)应用层(好多协议):负责应用程序之间的沟通。(面向用户的需求)比如:简单的电子邮件传输(SWTP)、文件传输协议 (FTP)、网络远程访问协议(Telnet)等。
一般而言:
(1).对于一台主机,它的操作系统内核实现了从传输层到物理层的内容。
(2)对于一台路由器,它实现了从网络层到物理层。
(3)对于一台交换机,它实现了从数据链路层到物理层。
(4)对于集线器,它只实现了物理层。
3.数据包封装和分用:
封装:应用层数据通过协议栈发到网络上时,每一次协议都要加上一数据首部的该过程。
分用:数据封装成帧后发送到传输介质上,到达目的主机后每层协议再剥掉相应的首部的该过程
下面用图示意:
二、网络编程套接字
1.IP地址:
1)IPV4和IPV6不兼容。
2)IP地址是在IP协议中,用来标识网络中不同主机的地址
3)对于IPV4来说,IP地址是一个4字节,32位的(无符号)整数。
4)通常使用“点分十进制”的字符串表示IP地址,用点分割的每一个数字表示一个字节,范围是0--255.
5)IP地址有两个:源IP地址(从哪来),目的IP地址(到哪去)。
2.端口号
1)端口号是传输层协议的内容
2)端口号是一个2字节16位的整数(0--65535)
3)端口号标识一个进程。(进程ID是会变化的)告诉操作系统,当前这个数据交给哪一个进程来处理。
4)IP地址+端口号:标识网络上的某一台主机的某一个进程。
5)一个端口号只能被一个进程占用。(如果被多个进程占用,就不知要发送到哪里去)。一个进程可以使用多个端口号。
3.TCP协议
TCP(Transmission Control Protocol):传输控制协议
1)传输层协议
2)有连接(面向连接):先建立一种连接,确保可以传输(eg:打电话)
3)可靠传输:使用某种方法保证数据不丢失(也因为是有连接,所以可靠)
4)面向字节流:数据之间没有明确的分割,数据无固定的格式,可以分开传输,分开接收。
5)全双工:有发送缓冲区,接收缓冲区,对于一个连接,既可以读也可以写。
4.UDP协议
UDP(User Datagram Protocol):用户数据报协议
1)传输层协议
2)无连接(面向无连接):不建立连接,不管对方是否能收到,自己只管发送。
3)不可靠传输:正因为是无连接,所以传输不可靠
4)面向数据报:数据之间不可以分开接收,要整体传输,整体接收。
5)全双工:UDP的socket能读也能写
5.面向字节序
1)面向字节序是一种数据存取的方式
2)网络数据流的地址规定:先发出的数据是低地址,后发出的数据是高地址
3)TCP/IP协议中规定:网络字节序-->大端字节序(数据的高位存放在低地址处)
主机字节序-->不固定的
4)大于1个字节的,就要大小端转换。
三、TCP协议和UDP协议的socket 操作流程
四、相关函数
1.创建socket (TCP/UDP; 客户端/服务器)
功能:建立与网卡驱动之间的一个联系
头文件: #include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
domain:协议簇(地址域),IPV4下为AF_INET:
type :1)TCP的流式套接字:SOCK_STREAM
2)UDP的数据报套接字:SOCK_DGRAM
protocol: 某种协议
TCP:IPPROTO_TCP (6)
UDP:IPPROTO_UDP (17)
2.绑定端口号(TCP/UDP; 服务器)
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
功能:为socket套接字绑定地址信息
3.监听(TCP ;服务器 )
int listen(int sockfd, int backlog);
backlog:表示同时最多有几个客户端连接成功
4.接受请求(TCP ;服务器)
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
5.建立连接(TCP ;客户端)
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen)
1)inet_addr:
in_addr_t inet_addr(const char *cp);
功能:将一个字符串IP地址--> 网络主机地址
2)inet_ntoa
char *inet_ntoa(struct in_addr in)
功能:将网络地址转换成点分十进制的字符串格式。
3)htonl :(长整型)
uint32_t htonl(uint32_t hostlong);
功能:将主机数转换成无符号长整形的网络字节序
4) htons:(短整形)
uint16_t htons(uint16_t hostshort)
功能:将主机数转换成无符号短整形的网络字节序
5)recvfrom:(UDP)
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen)
recvfrom函数中,socket* addrlen 不能为0
6)sendto:(UDP)
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);
recvfrom和sendto 的返回值:(成功)实际接收或是发送的数据的长度也不一定是想要的数据长度
(失败):-1
服务器先接收数据,客户端先发送数据。(服务器不知道客户端ip地址)
7)atoi
int atoi(const char *nptr);
三种地址结构:
TCP 创建套接字: