网络编程之客户端聊天(服务器加客户端共三种方式)

最终效果:

serve.c

复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/select.h>

#define MAX_CLIENTS 2  // 只允许两个客户端
#define BUF_SIZE 1024

int main(int argc, char *argv[]) {
    if (argc < 2) {
        printf("请输入端口号\n");
        return 1;
    }
    int port = atoi(argv[1]);

    int server_fd, client_fd, max_fd, activity, valread;
    int client_sockets[MAX_CLIENTS] = {0};  // 存储客户端 socket
    struct sockaddr_in server_addr, client_addr;
    socklen_t addr_len = sizeof(client_addr);
    char buffer[BUF_SIZE];

    fd_set read_fds;  // 监听集合

    // 创建服务器 socket
    server_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (server_fd == -1) {
        perror("Socket 创建失败");
        exit(1);
    }

    // 绑定地址和端口
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(port);
    if (bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        perror("绑定失败");
        exit(1);
    }

    // 监听连接
    if (listen(server_fd, 5) < 0) {
        perror("监听失败");
        exit(1);
    }

    printf("服务器启动,等待客户端连接...\n");

    while (1) {
        FD_ZERO(&read_fds);
        FD_SET(server_fd, &read_fds);
        max_fd = server_fd;

        // 添加客户端 socket
        for (int i = 0; i < 2; i++) {
            int sock = client_sockets[i];
            if (sock > 0) FD_SET(sock, &read_fds);
            if (sock > max_fd) max_fd = sock;
        }

        // 监听 socket 活动
        activity = select(max_fd + 1, &read_fds, NULL, NULL, NULL);
        if (activity < 0) {
            perror("select 错误");
            exit(1);
        }

        // 处理新连接
        if (FD_ISSET(server_fd, &read_fds)) {
            client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &addr_len);
            if (client_fd < 0) {
                perror("接受客户端失败");
                continue;
            }
            printf("新客户端连接\n");

            // 存入数组
            for (int i = 0; i < MAX_CLIENTS; i++) {
                if (client_sockets[i] == 0) {
                    client_sockets[i] = client_fd;
                    break;
                }
            }
        }

        // 处理客户端消息
        for (int i = 0; i < 2; i++) {
            int sock = client_sockets[i];
            if (FD_ISSET(sock, &read_fds)) {
                valread = read(sock, buffer, BUF_SIZE);
                if (valread == 0) {
                    printf("客户端断开连接\n");
                    close(sock);
                    client_sockets[i] = 0;
                } else {
                    buffer[valread] = '\0';
                    printf("客户端发送: %s\n",buffer);

                    // 找到另一个客户端
                    int other_client = (i == 0) ? client_sockets[1] : client_sockets[0];
                    if (other_client != 0) {
                        send(other_client, buffer, strlen(buffer), 0);
                    }
                }
            }
        }
    }

    return 0;
}

client1.c

复制代码
#include <head.h>


#define BUF_SIZE 1024

int main(int argc, char *argv[]) {
    if (argc < 2) {
        printf("请输入端口号\n");
        return 1;
    }
    char *server_ip ="192.168.61.94";
    int port = atoi(argv[1]);

    int sock;
    struct sockaddr_in server_addr;
    char buffer[BUF_SIZE];

    struct pollfd fds[2];

    // 创建 socket
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == -1) {
        perror("Socket 创建失败");
        exit(1);
    }

    // 连接服务器
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);
    inet_pton(AF_INET, server_ip, &server_addr.sin_addr);
    if (connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        perror("连接失败");
        exit(1);
    }

    printf("连接服务器成功,开始聊天...\n");

    fds[0].fd = sock;
    fds[0].events = POLLIN;
    fds[1].fd = STDIN_FILENO;
    fds[1].events = POLLIN;

    while (1) {
        poll(fds, 2, -1);

        if (fds[0].revents & POLLIN) {
            int len = read(sock, buffer, BUF_SIZE);
            if (len <= 0) {
                printf("服务器断开连接\n");
                break;
            }
            buffer[len] = '\0';
	printf("%s", buffer);
        }

        if (fds[1].revents & POLLIN) {
            fgets(buffer, BUF_SIZE, stdin);
            send(sock, buffer, strlen(buffer), 0);
        }
    }

    close(sock);
    return 0;
}

client2.c

复制代码
#include <head.h>

#define BUF_SIZE 1024

int sock;

void *receive_messages(void *arg) {
    char buffer[BUF_SIZE];
    while (1) {
        int len = read(sock, buffer, BUF_SIZE);
        if (len <= 0) {
            printf("服务器断开连接\n");
            exit(1);
        }
        buffer[len] = '\0';
        printf("%s", buffer);

    }
    return NULL;
}

int main(int argc, char *argv[]) {
    if (argc < 2) {
        printf("请输入端口号\n");
        return 1;
    }
    char *server_ip ="192.168.61.94";
    int port = atoi(argv[1]);

    struct sockaddr_in server_addr;
    char buffer[BUF_SIZE];

    sock = socket(AF_INET, SOCK_STREAM, 0);
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);
    inet_pton(AF_INET, server_ip, &server_addr.sin_addr);
    connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr));
    printf("连接服务器成功,开始聊天...\n");
    pthread_t recv_thread;
    pthread_create(&recv_thread, NULL, receive_messages, NULL);

    while (1) {
        fgets(buffer, BUF_SIZE, stdin);
        send(sock, buffer, strlen(buffer), 0);
    }

    close(sock);
    return 0;
}
相关推荐
虎头金猫1 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
AI职业加油站1 天前
AI智能体应用工程师证书:政策红利下的职业新风口
大数据·运维·人工智能·学习·职场发展
wuyk5551 天前
《WiFi 嵌入式物联网开发全套实战》| 第 16 章 ESP32 AP+STA 双模共存原理与工程坑点
网络·stm32·物联网
此冬歌咏1 天前
K8s 节点故障实战:优雅驱逐 31 秒,硬故障 331 秒,以及那个永远 Pending 的 Pod
运维·k8s
-梅2 天前
linux(8) 软硬链接
linux·运维·服务器
Wang's Blog2 天前
Java 项目实战: 外卖平台-文件下载与ServletOutputStream回写浏览器
服务器·项目开发
张洛闻Eren2 天前
k8s云原生【第十课】:水平 Pod 自动扩缩容
运维·数据库·云原生·kubernetes·github
琥珀色糖2 天前
SimlpeHttp
linux·服务器
其实防守也摸鱼2 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
第十人i2 天前
Linux 日志管理系统:journald 配置与优化
linux·服务器