网络编程
网络基础知识 tcp/udp tcp的通信模型
udp的通信模型 IO模型(epoll)
服务器模型 网络超时
多播 unix域套接字 数据库
数据库
笔试与面试考点:
网络基础知识 tcp三次握手 Tcp四次挥手
服务器
数据库SQL
工作或者大项目
tcp的通信模型
udp的通信模型
数据的处理 协议的制定
网络基础知识
OSI模型七层: ******
应用层、表示层、会话层、传输层、网络层、数据链路层、物理层
TCP/IP四层:******
应用层、传输层、网络层、网络接口和物理层
TCP/IP五层:**
应用层、传输层、网络层、数据链路层、物理层
协议: ***
规定 数据传输和解析相关的规定。
TCP/IP协议簇
应用层: HTTP、SMTP、DNS、TFTP、Telnet、FTP... ...
传输层:TCP、UDP
网络层:IP、ICMP、IGMP
网络接口和物理层:RARP、PPP、ARP
进程间通信
PIPE、FIFO、signal
shm、msgqueue
socket通信(套接字通信)
地址:(识别设备)
mac地址:硬件地址 48位的数
00:50:56:2f:e9:51
Bcast广播地址:192.168.9.255--》网段+主机号最大值
Mask子网掩码:255.255.255.0
ip地址:
ipv4:32位的数
192.168.9.131 --》网段+主机号--》点分十进制
ipv6:128位的数
fe80::250:56ff:fe2f:e951/64
域名:
字符串
端口号:(区分进程) 16位的数 --- unsigned short
0~65535
默认0~1024操作系统已经在用。
http:80端口 ftp:20、21端口 SMTP:25端口 telnet:23端口 tomcat:8080端口 tftp:69端口
自己的程序建议使用>50000
//DHCP 暂时借用 路由表
封包和解包
TCP协议 *****
特点(打电话)
传输层协议 建立连接 可靠性比较高 速度慢
三次握手
建立连接的过程
(拨号)客户端发送连接请求
(接听:喂,您好)服务器收到连接请求,给出回应
(您好,我是***)客户端发送确认连接
详细步骤:
第一次握手:建立连接时,客户端发送syn包(syn=j))到服务器,并进入SVN_SENT状态,等待服务器确认;SVN:同步序列编号(Synchronize SequenceNumbers) ;
第二次握手:服务器收到syn包,必须确认客户的SYN (ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+ 1),此包发送完毕,客户端和服务器进入ESTABLSHED(TCP连接成功》状态,完成三次握手。
四次挥手
断开连接的过程
(行,今天就聊到这)主机A给主机B发送断开连接的请求
(好的) 主机B收到请求,给出回应//如果主机B还有别的消息,可以继续发送
(今天先这样) 主机B给主机A发送断开连接的请求
(好的,拜拜) 主机A收到请求,给出回应
详细步骤:
1)客户端揣进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
2)服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续—段时间,也就是整个CLOSE-WAIT状态持续的时间。
3)客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
4)服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1, ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
5)客户端收到服务器的连接释放报文后,必须发出确认,ACK=1, ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2ssMSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态.
6)服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撒销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。
UDP协议 *****
特点(短信)
传输层协议 不需要建立连接 可靠性比较差 速度快
应用:
在线看视频,在线游戏
TCP协议通信模型
//TCP通信 客户端
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#define IP "127.0.0.1" //本机测试地址
#define CRORT 10010 //服务器端口
#define SPORT 10086 //客户端端口
#define SIZE 100
int main()
{
//1.定义变量
int sockfd = 0;
struct sockaddr_in addr;
int addrlen = 0;
char buf[SIZE] = {"hellword"};
//2.创建socket
//参数1:地址族--->使用网络协议族
//参数2:套接字类型---->使用流式套接字
//参数3:通常设置为0
sockfd = socket(PF_INET,SOCK_STREAM,0);
if(0 > sockfd)
{
perror("socket error");
return -1;
}
printf("socket ok\n");
//3.绑定地址(自己)
addrlen = sizeof(addr);
/*memset(&addr,0,addrlen);
addr.sin_family = PF_INET; //地址族--->使用网络协议族
addr.sin_port = htons(SPORT); //htons(主机字节序转换网络字节序函数),short短整型---->设置端口
addr.sin_addr.s_addr = INADDR_ANY; //获得IP地址(32位的网络字节序二进制值),转换过来就是0.0.0.0,泛指本机的意思,也就是表示本机的所有IP
if(0 > bind(sockfd,(struct sockaddr *)&addr,addrlen))
{
perror("bind error");
close(sockfd);
return -1;
}*/
printf("系统默认绑定bind ok\n");
//4.设置服务器地址,并且发送连接请求
memset(&addr,0,addrlen);
addr.sin_family = PF_INET; //地址族--->使用网络协议族
addr.sin_port = htons(CRORT); //htons(主机字节序转换网络字节序函数),short短整型---->设置端口
addr.sin_addr.s_addr = INADDR_ANY; //获得IP地址(32位的网络字节序二进制值)
if(0 > connect(sockfd,(struct sockaddr *)&addr,addrlen))
{
perror("connect error");
close(sockfd);
return -1;
}
printf("connect ok\n");
//5.通信
//参数3:通常设置为0
send(sockfd,buf,strlen(buf),0);
//6.关闭套接字
close(sockfd);
return 0;
}
//TCP通信 服务器
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h> /*memset*/
#include <unistd.h> /*close*/
#define IP "127.0.0.1" //本机测试地址
#define CPORT 10010 //服务器端口
#define SIZE 100
int main()
{
//1.设置变量
int sockfd = 0;
struct sockaddr_in addr;
int addrlen = 0;
int newID = 0;
char buf[SIZE] = {'\0'};
//2.创建socket套接字
//参数1:地址族--->使用网络协议族
//参数2:套接字类型---->使用流式套接字
//参数3:通常设置为0
sockfd = socket(PF_INET, SOCK_STREAM, 0);
if(0 > sockfd)
{
perror("socket error");
return -1;
}
printf("socket ok\n");
//3.绑定地址(自己)ip+port端口
addrlen = sizeof(addr);
memset(&addr,0,addrlen);
addr.sin_family = PF_INET; //地址族--->使用网络协议族
addr.sin_port = htons(CPORT); //htons(主机字节序转换网络字节序函数),short短整型---->设置端口
addr.sin_addr.s_addr = inet_addr(IP); //inet_addr(IP地址的转换),转换成32位的网络字节序二进制值
if(0 > bind(sockfd,(struct sockaddr *)&addr,addrlen))
{
perror("bind error");
close(sockfd); //关闭套接字
return -1;
}
printf("bind ok\n");
//4.建立监听----->socket变为被动,只能用于三次握手
//参数2:监听队列存放三次握手还没有结束的客户端
if(0 > listen(sockfd,5))
{
perror("listen error");
close(sockfd); //关闭套接字
return -1;
}
printf("listen ok\n");
//5.接受连接------>若成功,返回已经连接的套接字
newID=accept(sockfd, (struct sockaddr *)&addr,&addrlen);
if(0 > newID)
{
perror("accept error");
close(sockfd); //关闭套接字
return -1;
}
printf("accept ok\n");
//6.通信----->接收 发送 使用已经连接的套接字
//参数3:通常设置为0
//参数2:为什么用不了strlen测buf有效长度
recv(newID, buf, sizeof(buf)-1,0);
printf("服务器已收到:%s\n",buf);
//7.关闭已经连接的套接字
close(newID);
//8.关闭socket
close(sockfd);
return 0;
}
socket通信(套接字通信)的三要素
ip地址 协议 port端口号
192.168.1.10 tcp 80
192.168.1.10 udp 80
//大端序 小端序 字符串转数字 数字转字符串
TCP协议通信的一些细节:
1. bind:
a. 绑定的是自己的地址,包括ip+port端口号
b. 自己的ip地址操作系统可以获取,所以,在绑定时,建议写INADDR_ANY
c. 绑定的端口号和socket描述符是一对一的。
d. 如果自己不调用bind进行绑定,操作系统会有默认的绑定。
建议发送端不调用bind进行绑定,让操作系统默认绑定。
2. listen:
服务器建立一个监听队列,存放三次握手还没有结束的客户端。
如果三次握手结束,就会从当前队列移除。
文件下载