1. TCP和UDP的区别
特性 | TCP | UDP |
---|---|---|
连接类型 | 面向连接(三向握手四次挥手) | 无连接 |
可靠性 | 可靠传输,会重传 | 不可靠传输,会丢包 |
开销 | 较大 | 较小 |
应用场景 | 文件传输、电子邮件、网页浏览 | 视频会议、在线游戏、语音通话 |
流量控制 | 有 | 无 |
拥塞控制 | 有 | 无 |
2. TCP的三次握手过程
-
第一次握手(SYN):
客户端发送一个带有SYN标志的段(SYN=1),并选择一个初始序号(ISN,Initial Sequence Number)。
客户端进入SYN_SENT状态。
这个接段表示客户端希望建立连接,并且它的序号字段包含客户端选择的初始序号。
-
第二次握手(SYN-ACK):
服务器收到客户端的SYN段后,发送一个带有 SYN 和 ACK标志的段(SYN=1, ACK=1)。
服务器选择自己的初始序号,并将这个序号放在序号字段中。
服务器的 ACK 字段设置为客户端初始序号加1,表示确认收到了客户端的 SYN 段。
服务器进入 SYN_RCVD 状态。
-
第三次握手(ACK):
客户端收到服务器的 SYN-ACK 段后,发送一个带有 ACK 标志的段(ACK=1)。
客户端的 ACK 字段设置为服务器初始序号加1,表示确认收到了服务器的 SYN 段。
客户端进入 ESTABLISHED 状态。
服务器收到客户端的 ACK 段后,也进入 ESTABLISHED 状态。
3. TCP的四次挥手过程?为什么是四次挥手?
-
第一次挥手(FIN):
- 客户端发送一个带有
FIN
标志的段(FIN=1),表示客户端已经没有数据要发送了。 - 客户端进入
FIN_WAIT_1
状态。
- 客户端发送一个带有
-
第二次挥手(ACK):
- 服务器收到
FIN
段后,发送一个带有ACK
标志的段(ACK=1),确认序号为客户端FIN
段的序号加1。 - 服务器进入
CLOSE_WAIT
状态。 - 客户端收到
ACK
段后,进入FIN_WAIT_2
状态。
- 服务器收到
-
第三次挥手(FIN):
- 服务器发送一个带有
FIN
标志的段(FIN=1),表示服务器也没有数据要发送了。 - 服务器进入
LAST_ACK
状态。
- 服务器发送一个带有
-
第四次挥手(ACK):
- 客户端收到
FIN
段后,发送一个带有ACK
标志的段(ACK=1),确认序号为服务器FIN
段的序号加1。 - 客户端进入
TIME_WAIT
状态,等待一段时间后(通常是2MSL,即两倍的最大段生存时间)关闭连接。 - 服务器收到
ACK
段后,关闭连接,进入CLOSED
状态。
- 客户端收到
4. 在最后一次挥手时客户端为什么要等待2MSL?
确保最后一个 ACK
段到达服务器:
防止 ACK
段丢失导致服务器重新发送 FIN
段。
防止旧的数据包干扰新的连接:
确保所有与旧连接有关的数据包已经在网络中消失,避免数据混乱或错误。
5. TCP是如何保证可靠传输的
首先是三向握手和四次挥手确保上行和下行都是良好的
每个数据段都有一个唯一的序列号
使用ACK返回机制,确认号表示期望收到的下一个数据段的序号。
具有差错检测机制,每个数据段都包含一个校验和,用于检测数据在传输过程中是否发生错误。
有阻塞控制和流量控制机制,弱网以及性能不足也能收发信号。
6. 如何实现并发服务器
使用多线程和并发处理函数Select、poll、epoll等
socket,bind,listen,epoll,while(1){……}
7. Select、poll、epoll的区别?Select有什么优点?
select
可以监视多个文件描述符,等待其中任何一个文件描述符变为可读、可写或发生异常条件select
有一个固定的文件描述符数量限制(通常是1024)
poll
也用于监视多个文件描述符的状态变化。不同的是,poll
没有文件描述符数量的限制。
epoll
是 Linux 特有的 I/O 多路复用函数,epoll
通过事件驱动的方式工作,只有当某个文件描述符就绪时才会通知应用程序。使用边缘触发模式可以进一步优化性能
Select的优点是具有很好的平台兼容性,可以随意移植,代码简单易用,适合小型项目以及简单的应用场景
8. Tcp的粘包问题
解决沾包的问题有很多方法,比如加入消息头(包含消息的长度),发送定长的消息(比如1024字节),在每条消息之间添加一个特殊的分隔符。处理 TCP 粘包问题的关键在于设计合理的协议,确保接收方能够正确解析出消息的边界。
9. UDP的丢包问题
用于udp是无连接的协议,网络不好时无法避免会丢包,可以设计应答重传机制,类似于TFTP,给数据包编号,在客户端设计应答机制,在服务器端设计定时重传。
10. TCP编程框架
服务器端:
struct sockaddr_in sin;
sin.sin_family = AF_INET; //通信域
sin.sin_port = htons(SER_PORT); //端口号
sin.sin_addr.s_addr = inet_addr(SER_IP); //ip地址
int socket([ipv4/v6],[TCPUDP], 0);
int bind([套接字名],[地址信息] , sizeof([地址信息结构体]));
int listen([套接字名],[长度一般填128]);
int accept([套接字名], [地址信息接收指针] , [地址信息的长度]);
ssize_t recv([套接字名], void *buf, sizeof (buf), [阻塞或非阻塞]);
ssize_t send([新套接字名], void *buf, sizeof (buf), [阻塞或非阻塞]);
int connect([套接字名] ,[对端地址信息结构体], sizeof([对端地址信息结构体]));
客户端模型:
1.cfd = socket(AF_INET, SOCK_STREAM, 0);
//2.1 填充地址信息结构体
struct sockaddr_in cin;
cin.sin_family = AF_INET; //通信域
cin.sin_port = htons(CLI_PORT); //端口号
cin.sin_addr.s_addr = inet_addr(CLI_IP); //ip地址
2.bind(cfd, (struct sockaddr*)&cin, sizeof(cin))
//3.1 填充服务器地址信息结构体
struct sockaddr_in sin;
sin.sin_family = AF_INET; //通信域
sin.sin_port = htons(SER_PORT); //服务器端口号
sin.sin_addr.s_addr = inet_addr(SER_IP); //服务器ip地址
3.connect(cfd, (struct sockaddr*)&sin, sizeof(sin) //将套接字文件描述符连接到addr指向的地址空间中
while(1)
{
4.send(cfd, buf, strlen(buf), 0);
5.recv(cfd, buf, sizeof(buf), 0);
}
6.close();
原文链接:https://blog.csdn.net/sjrhsk_hahaha/article/details/141440609
11. 用过抓包工具么?抓过什么数据包?
wireshark 抓包的过程:选择网卡,选择端口号然后就可以抓取到数据了,可以抓取tcp通信和udp通信等的数据包。比如握手挥手之类
12. 广播和组播的区别
广播是指将数据包发送到网络中所有设备的过程,广播地址:网络号 + 255。
组播是指将数据包发送到一组特定的设备的过程。在组播传输中,发送方将数据包发送到一个组播地址,只有加入该组播组的设备才会接收到数据包。组播使用 D类 IP 地址(224——239)。
13. Tcp/ip网络模型分为几层?每一层什么作用?都有哪些协议?
TCP/IP网络体系结构四层:
应用层:Telnet、ftp、http、dns、smtp等
传输层:tcp和udp
网络层:IP、ICMP和IGMP
链路层(网络接口和物理层):以太网、令牌环网、FDDI等
14. OSI模型?
物链网运会表应
物理层
数据链路层
网络层
传输层
会话层
表示层
应用层
15. 学过什么数据库?增删改查语句?
太多了,略()