服务端
tcp_server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define BUF_SIZE 1024 // 定义一个宏,用于设置缓冲区大小为1024字节
int main() { // 主函数入口
int iServer, iClient; // 声明服务器和客户端socket变量
struct sockaddr_in stServer, stClient; // 声明服务器和客户端的地址结构体
char buf[BUF_SIZE]; // 声明一个字符数组,用于存储接收到的数据
// 创建socket
iServer = socket(AF_INET, SOCK_STREAM, 0); // 创建一个IPv4的TCP socket
if (iServer == -1) { // 如果socket创建失败
perror("socket error"); // 输出错误信息
exit(1); // 退出程序
}
// 绑定地址和端口
memset(&stServer, 0, sizeof(stServer)); // 初始化服务器地址结构体,设置为全0
stServer.sin_family = AF_INET; // 设置地址族为IPv4
stServer.sin_addr.s_addr = INADDR_ANY; // 设置服务器IP地址为任意地址(监听所有网络接口)
stServer.sin_port = htons(12345); // 设置服务器端口为12345,htons函数用于将主机字节序转换为网络字节序
if (bind(iServer, (struct sockaddr *)&stServer, sizeof(stServer)) == -1) { // 绑定socket到地址和端口
perror("bind error"); // 如果绑定失败,输出错误信息
exit(1); // 退出程序
}
// 监听连接
if (listen(iServer, 5) == -1) { // 开始监听连接,最大挂起连接数为5
perror("listen error"); // 如果监听失败,输出错误信息
exit(1); // 退出程序
}
// 接收客户端连接
socklen_t len = sizeof(struct sockaddr_in); // 声明一个socklen_t变量,用于存储地址结构体的长度
iClient = accept(iServer, (struct sockaddr *)&stClient, &len); // 等待并接受客户端的连接请求
if (iClient == -1) { // 如果接受连接失败
perror("accept error"); // 输出错误信息
exit(1); // 退出程序
}
printf("accept ok! iClient = %d\n", iClient); // 打印接受的客户端socket的描述符
// 与客户端进行持续通信
while (1) { // 无限循环,用于持续接收和发送数据
memset(buf, 0, BUF_SIZE); // 清空缓冲区
int ret = recv(iClient, buf, BUF_SIZE - 1, 0); // 从客户端接收数据,注意缓冲区大小减1以留出空间给字符串结束符'\0'
if (ret <= 0) { // 如果接收数据失败或客户端关闭连接
if (ret == 0) { // 如果接收到的数据长度为0,说明客户端正常关闭连接
printf("Client closed the connection\n"); // 打印提示信息
} else { // 如果接收失败
perror("recv error"); // 输出错误信息
}
break; // 跳出循环,结束通信
}
printf("recv data ok! buf = %s\n", buf); // 打印接收到的数据
// 回显数据给客户端
ret = send(iClient, buf, strlen(buf), 0); // 将接收到的数据(作为字符串)回显给客户端
if (ret <= 0) { // 如果发送数据失败
perror("send error"); // 输出错误信息
break; // 跳出循环,结束通信
}
printf("send data ok! %s\n", buf); // 打印发送的数据(注:这里实际上已经打印过了接收的数据,可能只是想表明发送成功)
}
// 关闭客户端连接
close(iClient); // 关闭与客户端的连接
printf("Connection with client closed\n"); // 打印连接已关闭的信息
// 关闭服务器socket(如果需要)
close(iServer); // 关闭服务器socket
return 0; // 程序正常结束,返回0
}
客户端
tcp_client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define BUF_SIZE 1024 // 定义一个宏,用于设置缓冲区大小为1024字节
int main() { // 主函数入口
int iClient; // 声明客户端socket变量
struct sockaddr_in stServer; // 声明服务器地址结构体
char buf[BUF_SIZE]; // 声明一个字符数组,用于存储接收和发送的数据
// 创建socket
// 创建一个IPv4的TCP socket
iClient = socket(AF_INET, SOCK_STREAM, 0);
if (iClient == -1) { // 如果socket创建失败
perror("socket error"); // 输出错误信息
exit(1); // 退出程序
}
// 设置服务器地址和端口
// 初始化服务器地址结构体,设置为全0
memset(&stServer, 0, sizeof(stServer));
stServer.sin_family = AF_INET; // 设置地址族为IPv4
// 假设服务器和客户端在同一台机器上,设置服务器IP地址为127.0.0.1
stServer.sin_addr.s_addr = inet_addr("127.0.0.1");
stServer.sin_port = htons(12345); // 设置服务器端口为12345,htons函数用于将主机字节序转换为网络字节序
// 连接到服务器
// 尝试连接到服务器
if (connect(iClient, (struct sockaddr *)&stServer, sizeof(stServer)) == -1) {
perror("connect error"); // 如果连接失败,输出错误信息
exit(1); // 退出程序
}
printf("connect ok!\n"); // 打印连接成功的消息
// 与服务器进行持续通信
while (1) { // 无限循环,用于持续接收和发送数据
printf("Enter message to send (or 'quit' to exit): "); // 提示用户输入要发送的消息或输入'quit'退出
// 读取用户输入
// 从标准输入读取最多BUF_SIZE-1个字符到buf中,并保留一个位置给字符串结束符'\0'
fgets(buf, BUF_SIZE - 1, stdin);
// 移除换行符(如果存在)
// 找到换行符并替换为字符串结束符'\0'
buf[strcspn(buf, "\n")] = 0;
// 检查是否输入了'quit'
// 如果用户输入的是'quit',则跳出循环
if (strcmp(buf, "quit") == 0) {
break;
}
// 发送数据到服务器
// 将用户输入的数据发送到服务器
int ret = send(iClient, buf, strlen(buf), 0);
if (ret <= 0) { // 如果发送数据失败
perror("send error"); // 输出错误信息
break; // 跳出循环,结束通信
}
// 接收服务器回显的数据
// 清空缓冲区以准备接收新数据
memset(buf, 0, BUF_SIZE);
// 从服务器接收数据到buf中
ret = recv(iClient, buf, BUF_SIZE - 1, 0);
if (ret <= 0) { // 如果接收数据失败或服务器关闭连接
if (ret == 0) { // 如果接收到的数据长度为0,说明服务器正常关闭连接
printf("Server closed the connection\n"); // 打印提示信息
} else { // 如果接收失败
perror("recv error"); // 输出错误信息
}
break; // 跳出循环,结束通信
}
// 打印从服务器接收到的数据
printf("Received from server: %s\n", buf);
}
// 关闭连接
// 关闭与服务器的连接
close(iClient);
printf("Connection with server closed\n"); // 打印连接已关闭的信息
return 0; // 程序正常结束,返回0
}