以下是一个简单的基于 TCP/IP 协议的聊天程序,使用了 C 语言和 Socket 编程:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

#define PORT 8888
#define MAX_CLIENTS 10
#define MAX_MSG_LENGTH 1024

int main(int argc, char **argv) {
    int server_fd, client_fds[MAX_CLIENTS], max_fd, activity, i, valread, sd;
    struct sockaddr_in address;
    char buffer[MAX_MSG_LENGTH];
    fd_set readfds;
    char *welcome_msg = "Welcome to the chat room!\n";
    int addrlen = sizeof(address);

    // create server socket
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    // set socket options
    int opt = 1;
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
        perror("setsockopt failed");
        exit(EXIT_FAILURE);
    }

    // bind socket to port
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(PORT);
    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }

    // listen for incoming connections
    if (listen(server_fd, 3) < 0) {
        perror("listen failed");
        exit(EXIT_FAILURE);
    }

    // clear client_fds array
    for (i = 0; i < MAX_CLIENTS; i++) {
        client_fds[i] = 0;
    }

    // add server_fd to readfds set
    FD_ZERO(&readfds);
    FD_SET(server_fd, &readfds);
    max_fd = server_fd;

    printf("Server started on port %d\n", PORT);

    while (1) {
        // wait for activity on any of the sockets
        activity = select(max_fd + 1, &readfds, NULL, NULL, NULL);
        if (activity < 0) {
            perror("select failed");
            exit(EXIT_FAILURE);
        }

        // handle activity on server_fd
        if (FD_ISSET(server_fd, &readfds)) {
            int new_socket;
            if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
                perror("accept failed");
                exit(EXIT_FAILURE);
            }

            // add new_socket to client_fds array
            for (i = 0; i < MAX_CLIENTS; i++) {
                if (client_fds[i] == 0) {
                    client_fds[i] = new_socket;
                    printf("New client connected, socket fd is %d, IP is %s, port is %d\n",
                        new_socket, inet_ntoa(address.sin_addr), ntohs(address.sin_port));
                    break;
                }
            }

            // send welcome message to new client
            send(new_socket, welcome_msg, strlen(welcome_msg), 0);

            // add new_socket to readfds set
            FD_SET(new_socket, &readfds);

            // update max_fd if necessary
            if (new_socket > max_fd) {
                max_fd = new_socket;
            }
        }

        // handle activity on client_fds
        for (i = 0; i < MAX_CLIENTS; i++) {
            sd = client_fds[i];
            if (FD_ISSET(sd, &readfds)) {
                valread = read(sd, buffer, MAX_MSG_LENGTH);
                if (valread == 0) {
                    // client has disconnected
                    getpeername(sd, (struct sockaddr*)&address, (socklen_t*)&addrlen);
                    printf("Client disconnected, socket fd is %d, IP is %s, port is %d\n",
                        sd, inet_ntoa(address.sin_addr), ntohs(address.sin_port));
                    close(sd);
                    client_fds[i] = 0;
                } else {
                    // broadcast message to other clients
                    buffer[valread] = '\0';
                    printf("Received message from client %d: %s", sd, buffer);
                    for (int j = 0; j < MAX_CLIENTS; j++) {
                        if (client_fds[j] != 0 && client_fds[j] != sd) {
                            send(client_fds[j], buffer, strlen(buffer), 0);
                        }
                    }
                }
            }
        }
    }

    return 0;
}

该程序使用了 select 函数来监听多个 socket 上的活动,并使用了一个数组来存储客户端的 socket 描述符。当有新客户端连接时,程序会将其添加到数组中,并向其发送欢迎消息。当有客户端发送消息时,程序会将该消息广播给其他客户端。当客户端断开连接时,程序会将其从数组中移除

参考下用c语言写的聊天软件

原文地址: https://www.cveoy.top/t/topic/d7pH 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录