目录
只有认知的突破 💫才能带来真正的成长 💫编程技术的学习 💫没有捷径 💫一起加油💫

🍁感谢各位的观看 🍁欢迎大家留言 🍁咱们一起加油 🍁努力成为更好的自己🍁
TCP通信
客户端:创建socket套接字------>connect建立链接------>sendto通信
服务端:创建socket套接字------>bind绑定------>listen监听------>accept接收请求
connect()和accept()函数都是阻塞式函数。
TcpServer.cc
cpp
#include <iostream>
#include <cstring>
// Linux网络编程核心头文件
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
using namespace std;
// 配置常量:监听端口、缓冲区大小(可自定义)
const int PORT = 8888;
const int BUF_SIZE = 1024;
int main() {
// 1. 创建TCP socket:AF_INET(IPv4)、SOCK_STREAM(TCP)、0(默认协议)
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd < 0) {
perror("socket create failed"); // 打印系统错误信息
return -1;
}
// 2. 配置服务端地址结构
sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr)); // 初始化地址内存
server_addr.sin_family = AF_INET; // IPv4协议
server_addr.sin_addr.s_addr = INADDR_ANY; // 监听本机所有网卡IP
server_addr.sin_port = htons(PORT); // 端口转网络字节序(大端)
// 3. 绑定socket与IP+端口
if (bind(server_fd, (sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
perror("bind failed");
close(server_fd);
return -1;
}
// 4. 开始监听:第二个参数为半连接队列大小(极简版设为5即可)
if (listen(server_fd, 5) < 0) {
perror("listen failed");
close(server_fd);
return -1;
}
cout << "服务端启动成功,监听端口:" << PORT << ",等待客户端连接..." << endl;
// 5. 接受客户端连接(阻塞式,直到有客户端连接)
sockaddr_in client_addr; // 存储客户端的地址信息
socklen_t client_addr_len = sizeof(client_addr);
int conn_fd = accept(server_fd, (sockaddr*)&client_addr, &client_addr_len);
if (conn_fd < 0) {
perror("accept failed");
close(server_fd);
return -1;
}
// 打印连接的客户端信息(IP+端口)
cout << "客户端连接成功:IP=" << inet_ntoa(client_addr.sin_addr)
<< ",Port=" << ntohs(client_addr.sin_port) << endl;
// 6. 读写数据:接收客户端消息并原内容回显
char buf[BUF_SIZE] = {0};
ssize_t recv_len = recv(conn_fd, buf, BUF_SIZE-1, 0); // 接收数据,保留1位存'\0'
if (recv_len < 0) {
perror("recv failed");
close(conn_fd);
close(server_fd);
return -1;
} else if (recv_len == 0) {
cout << "客户端主动关闭连接" << endl;
close(conn_fd);
close(server_fd);
return 0;
}
cout << "收到客户端消息:" << buf << endl;
// 回显消息给客户端
send(conn_fd, buf, strlen(buf), 0);
cout << "消息已回显给客户端" << endl;
// 7. 关闭文件描述符(Linux中socket是特殊文件描述符)
close(conn_fd); // 关闭与客户端的连接
close(server_fd); // 关闭服务端监听socket
return 0;
}
TcpClient.cc
cpp
#include <iostream>
#include <cstring>
// Linux网络编程核心头文件
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
using namespace std;
// 配置常量:服务端IP(本机测试用127.0.0.1)、服务端端口、缓冲区大小
const char* SERVER_IP = "127.0.0.1";
const int SERVER_PORT = 8888;
const int BUF_SIZE = 1024;
int main() {
// 1. 创建TCP socket(与服务端一致)
int client_fd = socket(AF_INET, SOCK_STREAM, 0);
if (client_fd < 0) {
perror("socket create failed");
return -1;
}
// 2. 配置服务端地址结构(用于指定连接目标)
sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
// 将服务端IP字符串转为网络字节序的32位整数
if (inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr) <= 0) {
perror("inet_pton failed (IP格式错误)");
close(client_fd);
return -1;
}
// 3. 连接服务端(阻塞式,直到连接成功或失败)
if (connect(client_fd, (sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
perror("connect failed(请检查服务端是否启动/IP+端口是否正确)");
close(client_fd);
return -1;
}
cout << "成功连接服务端:" << SERVER_IP << ":" << SERVER_PORT << endl;
// 4. 发送消息给服务端
char send_buf[BUF_SIZE] = {0};
cout << "请输入要发送的消息:";
cin >> send_buf; // 简单读取字符串(无空格,如需空格用cin.getline)
send(client_fd, send_buf, strlen(send_buf), 0);
cout << "消息已发送给服务端:" << send_buf << endl;
// 5. 接收服务端回显的消息
char recv_buf[BUF_SIZE] = {0};
ssize_t recv_len = recv(client_fd, recv_buf, BUF_SIZE-1, 0);
if (recv_len < 0) {
perror("recv failed");
close(client_fd);
return -1;
}
cout << "收到服务端回显消息:" << recv_buf << endl;
// 6. 关闭socket文件描述符
close(client_fd);
return 0;
}
总结
TCP协议的特点
-
传输层协议
-
有连接
-
可靠传输
-
面向字节流
UDP协议的特点
-
传输层协议
-
无连接
-
不可靠传输
-
面向数据报
