2. TCP回显客户端
任务目标
编写一个TCP客户端程序,能够连接到指定的服务器地址和端口,向服务器发送一条文本消息,并接收服务器返回的响应数据。通过本案例掌握C语言中socket编程的基本流程:创建套接字、连接服务器、发送数据、接收数据、关闭套接字。
环境依赖
- 操作系统:Linux(本案例代码使用Linux系统调用)
- 编译器:gcc
- 无需第三方库,仅使用系统标准库
完整代码
// tcp_client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define BUFFER_SIZE 1024
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "用法: %s <服务器IP> <端口>\n", argv[0]);
exit(EXIT_FAILURE);
}
const char *server_ip = argv[1];
int server_port = atoi(argv[2]);
// 1. 创建TCP套接字
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror("socket 创建失败");
exit(EXIT_FAILURE);
}
// 2. 配置服务器地址结构
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(server_port);
if (inet_pton(AF_INET, server_ip, &server_addr.sin_addr) <= 0) {
perror("无效的IP地址");
close(sock);
exit(EXIT_FAILURE);
}
// 3. 连接到服务器
if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("连接服务器失败");
close(sock);
exit(EXIT_FAILURE);
}
printf("已连接到 %s:%d\n", server_ip, server_port);
// 4. 发送数据
const char *message = "Hello, TCP Server!";
if (send(sock, message, strlen(message), 0) < 0) {
perror("发送数据失败");
close(sock);
exit(EXIT_FAILURE);
}
printf("已发送: %s\n", message);
// 5. 接收服务器响应
char buffer[BUFFER_SIZE];
memset(buffer, 0, sizeof(buffer));
int bytes_received = recv(sock, buffer, sizeof(buffer) - 1, 0);
if (bytes_received < 0) {
perror("接收数据失败");
close(sock);
exit(EXIT_FAILURE);
} else if (bytes_received == 0) {
printf("服务器已关闭连接\n");
} else {
printf("收到响应: %s\n", buffer);
}
// 6. 关闭套接字
close(sock);
return 0;
}
编译与运行
# 编译
gcc -o tcp_client tcp_client.c
# 运行(需要先启动一个TCP服务器)
./tcp_client 127.0.0.1 8080
验证方法
本案例需要配合一个TCP服务器进行测试。可以使用Linux自带的nc命令快速启动一个简易服务器:
# 终端1:启动监听服务器
nc -l 8080
# 终端2:运行客户端
./tcp_client 127.0.0.1 8080
通过条件:
- 客户端输出“已连接到 127.0.0.1:8080”和“已发送: Hello, TCP Server!”
- 在运行
nc的终端1中能看到收到的消息“Hello, TCP Server!” - 在
nc终端中手动输入一段文字并回车,客户端终端能打印出“收到响应: ”及对应内容
常见问题
- 连接失败(Connection refused):确认服务器已启动且端口号一致,检查IP地址是否正确。
- 发送后无响应:
recv会阻塞等待服务器数据,若服务器不发送数据,程序会一直等待。可在nc终端中手动输入内容触发响应。 - 端口占用:换用其他未被占用的端口(如 8888、9999)重新测试。