当前位置: 首页 > news >正文

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

最终效果:

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;
}

相关文章:

  • 智能家居安全革命:代理IP如何守护物联网世界
  • Elasticsearch:使用 ColPali 进行复杂文档搜索 - 第 1 部分 - 8.18
  • 穿越禁区:前端跨域通信的艺术与实践
  • Deployment声明式更新与应用式更新对比
  • Weblogic未授权远程命令执行漏洞复现
  • string(1):
  • 基于pycatia的CATIA装配体STP批量导出技术解析与优化指南
  • 分治-快速排序系列一>快速排序
  • VMWare:解决Linux虚拟机找不到共享文件夹
  • Java单元测试、Junit、断言、单元测试常见注解、单元测试Maven依赖范围、Maven常见问题解决方法
  • ubuntu高并发内核参数调优 - (压测客户端调优)
  • 【面试场景题-Redis中String类型和map类型的区别】
  • 蓝桥杯练习day2:执行操作后的变化量
  • 如何判断 MSF 的 Payload 是 Staged 还是 Stageless(含 Meterpreter 与普通 Shell 对比)
  • MySQL:数据库基础
  • 解决虚拟机网络问题
  • 【论文笔记】VGGT-从2D感知3D:pose估计+稠密重建+点跟踪
  • 爬虫基础之爬取猫眼Top100 可视化
  • 程序化广告行业(29/89):人群策略在广告投放中的应用
  • 法兰克仿真软件FANUC CNC Guide v25.0 安装教程及中文设置
  • 习近平给谢依特小学戍边支教西部计划志愿者服务队队员的回信
  • 增诉滥用职权罪,尹锡悦遭韩国检方追加起诉
  • 澎湃读报丨央媒头版集中刊发社论,庆祝“五一”国际劳动节
  • 印度宣布即日起对所有巴基斯坦航班关闭领空
  • 擦亮“世界美食之都”金字招牌,淮安的努力不止于餐桌
  • 朝鲜海军新型驱逐舰进行首次武器系统测试