网络编程---7.11

思维导图

网络编程---7.11_第1张图片

服务器代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include 

// 客户端连接的文件描述符(全局方便线程访问)
int client_fd;

// 线程函数:接收客户端消息
void* recv_msg(void* arg) {
    char buf[1024];
    while (1) {
        // 清空缓冲区
        memset(buf, 0, sizeof(buf));
        // 接收客户端消息
        int len = recv(client_fd, buf, sizeof(buf), 0);
        if (len <= 0) {
            printf("客户端断开连接或接收失败\n");
            close(client_fd);
            pthread_exit(NULL);
        }
        printf("客户端说:%s\n", buf);
    }
}

// 线程函数:向客户端发送消息
void* send_msg(void* arg) {
    char buf[1024];
    while (1) {
        // 从控制台输入消息
        memset(buf, 0, sizeof(buf));
        printf("你(服务器)想说:");
        fgets(buf, sizeof(buf), stdin);
        // 去掉换行符(fgets 会包含换行)
        buf[strcspn(buf, "\n")] = '\0';
        
        // 发送消息给客户端
        send(client_fd, buf, strlen(buf), 0);
    }
}

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

    // 1. 创建套接字
    int server_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (server_fd == -1) {
        perror("socket");
        return 1;
    }

    // 2. 绑定地址
    struct sockaddr_in addr = {0};
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = INADDR_ANY; // 绑定到所有网卡
    if (bind(server_fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
        perror("bind");
        close(server_fd);
        return 1;
    }

    // 3. 监听
    if (listen(server_fd, 10) == -1) {
        perror("listen");
        close(server_fd);
        return 1;
    }
    printf("服务器已启动,等待客户端连接...\n");

    // 4. 接受客户端连接
    struct sockaddr_in client_addr;
    socklen_t client_len = sizeof(client_addr);
    client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &client_len);
    if (client_fd == -1) {
        perror("accept");
        close(server_fd);
        return 1;
    }
    printf("客户端已连接:%s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

    // 5. 创建收发线程
    pthread_t recv_tid, send_tid;
    pthread_create(&recv_tid, NULL, recv_msg, NULL);
    pthread_create(&send_tid, NULL, send_msg, NULL);

    // 等待线程结束(实际聊天场景中线程会一直运行,这里只是形式)
    pthread_join(recv_tid, NULL);
    pthread_join(send_tid, NULL);

    // 6. 关闭套接字
    close(client_fd);
    close(server_fd);
    return 0;
}

 客户端代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include 

// 服务器连接的文件描述符(全局方便线程访问)
int server_fd;

// 线程函数:接收服务器消息
void* recv_msg(void* arg) {
    char buf[1024];
    while (1) {
        // 清空缓冲区
        memset(buf, 0, sizeof(buf));
        // 接收服务器消息
        int len = recv(server_fd, buf, sizeof(buf), 0);
        if (len <= 0) {
            printf("服务器断开连接或接收失败\n");
            close(server_fd);
            pthread_exit(NULL);
        }
        printf("服务器说:%s\n", buf);
    }
}

// 线程函数:向服务器发送消息
void* send_msg(void* arg) {
    char buf[1024];
    while (1) {
        // 从控制台输入消息
        memset(buf, 0, sizeof(buf));
        printf("你(客户端)想说:");
        fgets(buf, sizeof(buf), stdin);
        // 去掉换行符(fgets 会包含换行)
        buf[strcspn(buf, "\n")] = '\0';
        
        // 发送消息给服务器
        send(server_fd, buf, strlen(buf), 0);
    }
}

int main(int argc, const char* argv[]) {
    if (argc < 3) {
        printf("请输入:./client 服务器IP 端口号\n");
        return 1;
    }
    const char* server_ip = argv[1];
    short port = atoi(argv[2]);

    // 1. 创建套接字
    server_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (server_fd == -1) {
        perror("socket");
        return 1;
    }

    // 2. 连接服务器
    struct sockaddr_in addr = {0};
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    // 将字符串IP转为网络字节序
    if (inet_pton(AF_INET, server_ip, &addr.sin_addr) <= 0) {
        perror("inet_pton");
        close(server_fd);
        return 1;
    }
    if (connect(server_fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
        perror("connect");
        close(server_fd);
        return 1;
    }
    printf("已连接服务器:%s:%d\n", server_ip, port);

    // 3. 创建收发线程
    pthread_t recv_tid, send_tid;
    pthread_create(&recv_tid, NULL, recv_msg, NULL);
    pthread_create(&send_tid, NULL, send_msg, NULL);

    // 等待线程结束(实际聊天场景中线程会一直运行,这里只是形式)
    pthread_join(recv_tid, NULL);
    pthread_join(send_tid, NULL);

    // 4. 关闭套接字
    close(server_fd);
    return 0;
}

你可能感兴趣的:(网络,php,开发语言)