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

最终效果:

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;
}
相关推荐
ddfa123433 分钟前
XML 笔记
xml·服务器
海外空间恒创科技38 分钟前
一台香港原生ip站群服务器多少钱?
服务器·网络协议·tcp/ip
Charlene Fung42 分钟前
vs code远程自动登录服务器,无需手动输入密码的终极方案(windows版)
运维·服务器·vscode·ssh
碣石潇湘无限路1 小时前
【部署与总结】从本地运行到公网服务器的全过程
运维·服务器
linux修理工1 小时前
ipmitool 使用简介(ipmitool sel list & ipmitool sensor list)
运维·服务器
XM-54581 小时前
2025微信小程序wxapkg解包全攻略
linux·运维·小程序
zyx没烦恼1 小时前
TCP相关实验
服务器·网络·tcp/ip
朗晴2 小时前
文本编辑器VIM的使用方法!
linux·运维·服务器
小林up2 小时前
github push:ssh: connect to host github.com port 22
运维·ssh·github
mgx_7182 小时前
修改阿里云vps为自定义用户登录
服务器