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

最终效果:

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;
}
相关推荐
SummerGao.7 分钟前
Centos 7 安装达梦数据库
linux·运维·centos·达梦
Macle_Chen9 分钟前
Xcode16.1使用MonkeyDev运行Tiktok报错分析
linux·运维·服务器·ios
三天不学习1 小时前
Windows电脑 打开 Docker Desktop 提示的“Virtual Machine Platform not enabled”的问题解决
运维·docker·容器
w23617346013 小时前
以太网安全管理实验——ARP欺骗
网络·安全·智能路由器·ensp·arp·arp欺骗
小李苦学C++3 小时前
计算机网络基础
网络
晓夜残歌4 小时前
安全基线-rm命令防护
运维·服务器·前端·chrome·安全·ubuntu
leeezp7 小时前
配置固定ip绕过ip限制
运维·网络协议
阿正的梦工坊9 小时前
Linux top 命令详解:从入门到高级用法
linux·服务器·网络
遇见火星9 小时前
docker-compose 快速搭建日志平台
linux·运维·centos
她的双马尾9 小时前
WebSocket:开启实时通信的新篇章
网络·websocket·网络协议