一、网络协议层次与UDP协议基础
1.1网络层次:
网络原理包括网络协议的各层,如应用层、传输层、网络层、数据链路层、物理层 。自定义应用层协议需确定传输信息(对应需求)和组织信息的格式(如行文本、xml、json、protobuf 等 ),HTTP是常见应用层协议 。
-1.2UDP协议:
UDP报头格式简单,包含源端口、目的端口、长度、校验和 。由于UDP长度字段为2字节,数据范围0 - 65535 ,对应最大长度64KB ,传输大数据可能装不下 。校验和用于验证UDP数据报在传输中是否出错,因网络传输中存在比特翻转(如电信号、光信号、电磁波受环境影响 ),通过发送方计算校验和填充报头,接收方按相同算法计算并比较来判断数据是否出错 。
二、TCP协议报头与核心性质
2.2TCP报头:
TCP报头包含16位源端口号、16位目的端口号、32位序号、32位确认序号、4位首部长度、保留(6位) 、16位窗口大小、16位校验和、16位紧急指针、选项等 。首部长度因选项可选,范围0 - 15(以4字节为单位 ),决定报头最大长度 。
2.3核心性质
- 确认应答:实现可靠传输的核心机制,发送方发送数据后,接收方返回“应答报文”(ack ),发送方据此感知接收方是否收到数据,未收到则采取措施 。序号按字节编排连续递增,确认序号按收到数据的最后一个字节序号 + 1 。
- 超时重传:产生丢包后重新传输数据,可能是数据或ack丢失 。接收方按序号对数据去重 ,超时时间动态变化,重传次数和总重传时间存在上限,达上限未成功则“重置”连接(发送RST复位报文 ) 。
- 连接管理:TCP是有连接协议,连接是虚拟、抽象的,通信双方保存对方关键信息(如IP、端口 ) 。连接建立通过三次握手,连接断开通过四次挥手 。
三、TCP连接建立与断开
3.1 三次握手(连接建立)
- 过程:客户端给服务器发起一个syn(同步报文段 );服务器收到syn后,返回ack和发送syn ,这两步由内核控制,与应用程序代码无关;客户端收到服务器的ack + syn后,再返回ack 。从流程逻辑上是四次交互,但中间两次可合并,网络实际只传输三个数据包 。
- 意义:验证通信链路是否畅通,如地铁首发空车检查线路 ;验证通信双方发送和接收能力是否正常,如通过语音软件沟通前确认耳机和麦克风正常 ;协商关键信息,如TCP数据的起始序号 。每次建立连接协商的起始编号不同,避免旧数据包干扰新连接 。
3.2 四次挥手(连接断开)
- 过程:客户端发送FIN告知服务器要断开连接;服务器收到FIN后返回ACK ,此时服务器进入CLOSE_WAIT状态,等待应用程序代码调用close ;服务器处理完数据后,发送FIN告知客户端也要断开连接;客户端收到服务器的FIN后返回ACK ,此时客户端进入TIME_WAIT状态 。
- 状态:CLOSE_WAIT是被动断开连接一方进入的状态,正常存在时间短,若服务器出现大量该状态可能是代码未正确调用close 。TIME_WAIT是主动发起断开连接一方进入的状态,等待连接彻底释放,时长为2倍MSL(网络上任意两点间传输消耗的最大时间 ,如Linux默认60s ),是为应对最后一个ACK丢包情况 。
四、求职面试相关建议
4.1大厂招聘:
大厂常年招聘实习生(不定期 ),9、10月有固定校招,平时也招实习生 。不同时间招聘收到简历数量不同,如9、10月可能收到几份,5、6月可能收到几百份,12、1月可能收到20份 。
4.2 实习要点:
真正去公司实习的同学是同龄人佼佼者,公司希望长期实习,实习越久转正概率越高 。不要说自己是被学校强制实习或被骗去传销组织等负面言论 。投简历可从小厂开始积累面试经验,不要把第一场面试给心仪公司 。与面试官沟通要友好,若有更好offer可委婉说明 。
代码示例(以Java为例,补充示意TCP和UDP相关操作)
TCP服务器端代码示例
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer {
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(8888)) {
System.out.println("服务器启动,等待客户端连接...");
while (true) {
Socket socket = serverSocket.accept();
System.out.println("客户端连接成功");
new Thread(() -> {
try (InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream()) {
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) != -1) {
String data = new String(buffer, 0, len);
System.out.println("收到客户端消息: " + data);
// 简单回显
outputStream.write("已收到".getBytes());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
TCP客户端代码示例
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class TCPClient {
public static void main(String[] args) {
try (Socket socket = new Socket("localhost", 8888)) {
OutputStream outputStream = socket.getOutputStream();
outputStream.write("你好,服务器".getBytes());
InputStream inputStream = socket.getInputStream();
byte[] buffer = new byte[1024];
int len = inputStream.read(buffer);
String response = new String(buffer, 0, len);
System.out.println("收到服务器响应: " + response);
} catch (IOException e) {
e.printStackTrace();
}
}
}
UDP发送端代码示例
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPSender {
public static void main(String[] args) {
try (DatagramSocket socket = new DatagramSocket()) {
String message = "你好,UDP接收方";
byte[] data = message.getBytes();
InetAddress address = InetAddress.getByName("localhost");
int port = 9999;
DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
socket.send(packet);
System.out.println("UDP消息已发送");
} catch (IOException e) {
e.printStackTrace();
}
}
}
UDP接收端代码示例
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UDPReceiver {
public static void main(String[] args) {
try (DatagramSocket socket = new DatagramSocket(9999)) {
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
String message = new String(packet.getData(), 0, packet.getLength());
System.out.println("收到UDP消息: " + message);
} catch (IOException e) {
e.printStackTrace();
}
}
}