客户端连接断开之后还可以重新连接服务器的tcp服务器c代码
时间: 2023-09-28 17:12:22 浏览: 56
以下是一个简单的TCP服务器C代码示例,可以处理客户端断开连接后重新连接的情况:
```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define MAX_CLIENTS 10
int main(int argc, char **argv)
{
int server_fd, client_fds[MAX_CLIENTS], max_clients = MAX_CLIENTS;
struct sockaddr_in server_addr, client_addr;
char buffer[1024];
// 创建 TCP 套接字
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("socket failed");
exit(EXIT_FAILURE);
}
// 设置服务器地址
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(8080);
// 绑定服务器地址
if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
perror("bind failed");
exit(EXIT_FAILURE);
}
// 监听客户端连接
if (listen(server_fd, max_clients) < 0)
{
perror("listen failed");
exit(EXIT_FAILURE);
}
printf("Waiting for client connections...\n");
// 初始化客户端套接字数组
for (int i = 0; i < max_clients; i++)
{
client_fds[i] = 0;
}
while (1)
{
int max_sd = 0, activity = 0, sd = 0;
fd_set read_fds;
FD_ZERO(&read_fds);
FD_SET(server_fd, &read_fds);
// 添加客户端套接字到集合中
for (int i = 0; i < max_clients; i++)
{
sd = client_fds[i];
if (sd > 0)
{
FD_SET(sd, &read_fds);
}
if (sd > max_sd)
{
max_sd = sd;
}
}
// 等待客户端连接或数据到达
activity = select(max_sd + 1, &read_fds, NULL, NULL, NULL);
if ((activity < 0) && (errno != EINTR))
{
perror("select error");
}
// 处理新的客户端连接请求
if (FD_ISSET(server_fd, &read_fds))
{
int new_socket, addrlen = sizeof(client_addr);
if ((new_socket = accept(server_fd, (struct sockaddr *)&client_addr, (socklen_t *)&addrlen)) < 0)
{
perror("accept failed");
exit(EXIT_FAILURE);
}
printf("New client connection, socket fd is %d, ip is %s, port is %d\n", new_socket, inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
// 添加新的客户端套接字到数组中
for (int i = 0; i < max_clients; i++)
{
if (client_fds[i] == 0)
{
client_fds[i] = new_socket;
break;
}
}
}
// 处理客户端数据
for (int i = 0; i < max_clients; i++)
{
sd = client_fds[i];
if (FD_ISSET(sd, &read_fds))
{
int valread;
if ((valread = read(sd, buffer, 1024)) == 0)
{
// 客户端断开连接
printf("Client disconnected, socket fd is %d\n", sd);
close(sd);
client_fds[i] = 0;
}
else
{
// 处理客户端发送来的数据
buffer[valread] = '\0';
printf("Received data from client, socket fd is %d, data is %s\n", sd, buffer);
send(sd, buffer, strlen(buffer), 0);
}
}
}
}
return 0;
}
```
在上述代码中,我们使用了一个客户端套接字数组来存储连接到服务器的客户端套接字。当有新的客户端连接请求时,我们将新的客户端套接字添加到数组中。当客户端断开连接时,我们将相应的客户端套接字从数组中删除。
在处理客户端数据时,如果发现客户端套接字已经断开连接,则关闭该套接字并将其从数组中删除。如果客户端重新连接,则会创建一个新的套接字并分配一个新的文件描述符,因此我们需要使用新的文件描述符来处理重新连接的客户端。
总的来说,以上代码示例可以处理客户端断开连接后重新连接的情况。如果需要更复杂的功能,例如客户端重连时保持之前的状态等,需要根据具体的应用场景进行修改。