编程套接字
目录
- 基础概念
- Socket API详解
- UDP编程
- TCP编程
- 地址转换函数
- TCP vs UDP
- 总结
基础概念
IP地址与端口号
- IP地址:标识网络中的一台主机(如
192.168.1.1)。
- 端口号:2字节整数(0-65535),标识主机上的进程。
示例:QQ消息需通过IP地址发送到目标机器,再通过端口号区分具体进程。
网络字节序
TCP与UDP协议对比
| 特性 |
TCP |
UDP |
| 连接方式 |
有连接(三次握手) |
无连接 |
| 可靠性 |
可靠传输 |
不可靠传输 |
| 数据形式 |
字节流 |
数据报 |
| 典型场景 |
文件传输、网页浏览 |
实时视频、DNS查询 |
Socket API详解
核心函数
int socket(int domain, int type, int protocol); // 创建socket
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); // 绑定端口
int listen(int sockfd, int backlog); // 监听连接
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); // 接受连接
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); // 建立连接
关键数据结构
UDP编程
服务器实现(C++示例)
// 创建UDP Socket并绑定端口
UdpSocket sock;
sock.Socket();
sock.Bind("0.0.0.0", 8888);
// 接收数据
std::string req, client_ip;
uint16_t client_port;
sock.RecvFrom(&req, &client_ip, &client_port);
// 发送响应
std::string resp = "Hello from server!";
sock.SendTo(resp, client_ip, client_port);
客户端实现
UdpClient client("127.0.0.1", 8888);
client.SendTo("Hello from client!");
std::string resp;
client.RecvFrom(&resp);
TCP编程
单线程服务器
TcpServer server("0.0.0.0", 9999);
server.Start([](const std::string& req, std::string* resp) {
*resp = "Response: " + req;
});
多进程版本
// 父进程处理连接请求后fork子进程
int ret = fork();
if (ret == 0) {
// 子进程处理数据读写
ProcessRequest(new_sock);
exit(0);
}
多线程版本
pthread_t tid;
pthread_create(&tid, NULL, ThreadEntry, arg); // 创建线程处理请求
pthread_detach(tid); // 分离线程
地址转换函数
- 字符串转IP:
inet_aton("127.0.0.1", &addr.sin_addr);
- IP转字符串:
char* ip_str = inet_ntoa(addr.sin_addr);
- 注意:
inet_ntoa 非线程安全,推荐使用 inet_ntop。
TCP vs UDP
三次握手与四次挥手
- 三次握手:
- 客户端发送SYN
- 服务端回复SYN-ACK
- 客户端发送ACK
- 四次挥手:
- 客户端发送FIN
- 服务端回复ACK
- 服务端发送FIN
- 客户端回复ACK
适用场景
- TCP:需可靠传输的场景(如HTTP、FTP)。
- UDP:低延迟、可容忍丢包(如直播、VoIP)。
总结
- TCP 提供可靠连接,适合需要数据完整性的场景。
- UDP 轻量高效,适合实时性要求高的场景。