linux网络编程:重点TCP—UDP协议
1.OSI模型与TCP/IP协议体系结构
2.TCP/IP协议---传输控制协议TCP(transport control protocol)和互联网协议IP
3.TCP和UDP协议
体系结构:(理解)网络的层次结构和每一层所使用协议的集合。。。
1.将网络的功能划分为不同的模块,以分层的形式有机组合在一起。
2.两类重要的体系结构:OSI和TCP/IP 两者的区别:??前者理想化后者事实上得工业标准采用的 即分层不同。。。
OSI开放系统互联模型:
1.OSI的七层结构
最下层:物理层----比特流,无格式的01二进制的串。。。。。
链路层---数据组成可发送、接收的帧 MAC地址:6字节,前3个字节固定为公司的标识符。
网络层---IP地址(源主机,和目标主机的IP地址)主要的功能:为数据包选择路由。
传输层---提供可靠的数据传输。。(端口号)内核对外提供的最外一层。。
会话层---实际中一般没有,了解。。。
表示层---数据格式的定义和数据转换/加密
应用层---应用程序,文件传送输
2.TCP/IP协议族的体系结构:(4层)
应用层---Telnet 和 FTP等
传输层---TCP和UDP
网络层---IP ICMP IGMP
网络接口和物理层
ARP协议:根据IP地址获得MAC地址; RARP协议:根据MAC地址获得IP地址
3.TCP和UDP协议
共同点:都是传输协议
不同点:TCP:有链接,可靠。。而UDP:无连接,不保证可靠
4.TCP协议特点:
高可靠性通信:数据无误(TCP校验),数据无丢失(丢了,给用户重新发送),数据无失序(不能保证先来先发,但根据包的序号,进行排序),数据无重复到达的通信。(高可靠性------4无产品)
5.socket:
它是一种系统关于网络编程的接口;是一种特殊的文件描述符;
socket类型:流式套接字----运用在TCP协议;数据报套接字----运用于UDP协议; 原始套接字-----运用于较低层次协议如IP,ICMP。。。
6.IP地址:是Internet中主机的标识。
表示形式:常用点分形式,如:192.168.1.66,最后都会转换为一个32位的无符号整数。
IP地址的转换:inet_aton()将所有字符串转换为32位的网络字节序二进制值。
inet_addr()功能同上,返回转换后的地址。
inet_ntoa()将32位的网络字节序二进制地址转换成点分十进制的字符串。
7.端口号:
区别一台主机接收到的数据包应该转交给那个进程来进行处理,使用端口来区别。
TCP端口号和UDP端口号独立。
网络通信三元组合:IP,端口,协议。。。。
8. 字节序:内存存储多字节整数序列有两种方法,称为主机字节序。
小端:低序字节存储在低地址。
大端:高序节存储在低地址。
网络中传输的数据必须按网络字节序,即大端字节序。
在大部分PC机上,当应用进程将证书传入socket前需要转换成网络字节序。
字节序转换函数:
主机字节序到网络字节序:
u_long htonl (u_long hostlong);
u_short htons (u_short short);
网络字节序到主机字节序:
ulong ntohl (u_long hostlong);
u_short ntohs (u_short short);
9.网络编程相关API:
int socket(int domain, int type, int protocol);
domain:是地址族。
PF_INET //网络通信。
PF_UNIX //本地通信。
type:套接字类型
SOCK_STREAM //流式套接字
SOCK_DGRAM //数据包套接字
SOCK_RAW //原始套接字
protocol:协议编号,除了使用原始套接字,均用0。
int bind(int sockfd, struct sockaddr *my_addr, int addrlen); 返回值 0 和 -1
sockfd:socket调用返回的文件描述符。
addrlen:sockaddr地址结构的长度==sizeof(myaddr)
通用地址结构:
struct sockaddr
{
u_short sa_family; //地址族,2个字节
char sa_data[14]; //14字节协议地址
};
网络地址结构:
struct sockaddr_in
{ 生成实例后不要忘记bzero(&变量, sizeof(变量));
u_short sin_family; //地址族 2个字节 PF_INET
u_short sin_port; //端口号 2个字节 htons(6000)
struct in_addr sin_addr; //IPV4地址 4个字节 inet_addr(…)
char sin_zero[8]; //作为填充,8个字节 …
};
本地通信:
struck sockaddr_un
{
…….
}
int listen(int sockfd, int backlog); //TCP服务器端使用的函数。
只有调用了listen以后将sockfd改成被动模式,才能实现监听,等待请求。
backlog:等待队列的长度,能允许多少客户排队。
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
返回值:已建立好链接的套接字或-1。
sockfd:监听套接字。
addr:对方地址。不关心别人地址的话填入NULL。
addrlen:对方地址的长度。
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen); //TCP客户端使用的函数
返回值:0或-1
sockfd:socket返回的文件描述符。
serv_addr:服务器端的地址信息。
addrlen:serv_addr的长度。
ssize_t send(int socket, const void *buffer, size_t length, int flags);
返回值:成功返回实际发送的字节数,失败返回-1,并设置errno。
buffer:发送缓冲区首地址。
length:发送的字节数。
flags:发送方式,通常为0。
ssize_t recv(int socket, con void *buffer, size_t length, int flags);
返回值:成功返回实际接收的字节数。失败返回-1,并设置errno。
buffer:发送缓冲区首地址。
length:发送的字节数。
flags:接受方式,通常为0。
shutdown:
使用时强转为通用类型,因为结构体生成的实例大小一样。
10.服务器流程:
i.创建套接字
ii.绑定IP与端口号
iii.启动监听状态 接收连接(第二次握手)
iiii.发送请求服务(第三次握手)
11.客户端流程:
i.创建套接字
ii.绑定(可选自己绑定或是服务器自动分配)
iii.连接(第一次握手,连到服务器的监听)
iiii.创建新的套接字等待请求(分派服务)