在Linux下创建一个简单的TCP服务器,我们可以使用C语言和基本的socket编程。
以下是一个简单的TCP服务器程序,它监听指定端口,接受客户端连接,然后接收客户端发来的数据并原样发回(echo server)。
步骤:
1. 创建socket
2. 绑定socket到地址和端口
3. 监听连接
4. 接受连接
5. 读写数据
6. 关闭连接
注意:这个例子没有考虑多客户端并发,一次只能处理一个客户端。
我们将编写一个回显服务器,它会在8888端口上监听。
代码示例:
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 8888
#define BUFFER_SIZE 1024
int main() {
int server_fd, new_socket;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[BUFFER_SIZE] = {0};
// 1. 创建socket文件描述符
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
// 设置socket选项,允许地址和端口重用
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY; // 接受任意IP的连接
address.sin_port = htons(PORT); // 端口转换为网络字节序
// 2. 绑定socket到地址和端口
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
// 3. 监听连接,设置最大等待连接数为3
if (listen(server_fd, 3) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
printf("Server is listening on port %d...\n", PORT);
// 4. 接受连接
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
perror("accept");
exit(EXIT_FAILURE);
}
// 打印客户端IP地址
char client_ip[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &address.sin_addr, client_ip, INET_ADDRSTRLEN);
printf("Connection accepted from %s:%d\n", client_ip, ntohs(address.sin_port));
// 5. 读写数据
while (1) {
memset(buffer, 0, BUFFER_SIZE); // 清空缓冲区
ssize_t bytes_read = read(new_socket, buffer, BUFFER_SIZE - 1); // 读取数据
if (bytes_read <= 0) {
// 客户端断开连接或出错
perror("read error or client disconnected");
break;
}
printf("Received: %s", buffer);
// 将收到的数据原样发回
send(new_socket, buffer, strlen(buffer), 0);
printf("Echoed back: %s", buffer);
}
// 6. 关闭连接
close(new_socket);
close(server_fd);
return 0;
}
/*
编译:gcc server.c -o server
运行:./server
注意:
- 这个服务器是单线程的,一次只能处理一个客户端连接。要处理多个客户端,可以使用多进程、多线程或I/O多路复用(如select, poll, epoll)。
- 实际应用中需要更完善的错误处理和资源管理。
测试:
可以使用telnet或nc(netcat)工具来测试这个服务器。
例如:在另一个终端执行 `nc localhost 8888`,然后输入一些文本,服务器会将文本回显。
*/