如何接受多个客户端输入并使用套接字c显示它

问题描述 投票:0回答:1

我正在尝试用 C 语言制作一个简单的 CLI 消息传递。我发现了套接字。 我编写了一个简单的程序,客户端可以编写一些消息,服务器在服务器端打印它 我尝试打开多个客户端,但它只接受一个客户端,

我想制作一个程序,其中许多客户端可以加入服务器而不是一个并写入一些消息,目前只有服务器在服务器端打印客户端消息,但是当其他客户端加入时 并发送消息 我希望客户能够看到其他客户消息 目前我有 服务器.c

/*
server.c
*/

#include <stdio.h>
#include <unistd.h>
#include <strings.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define MAX 256
#define PORT 8080

int main() {
    int socket_return, accept_return, bind_return, listen_return;
    struct sockaddr_in server_address, peer_address;

    // Creating  socket
    socket_return = socket(AF_INET, SOCK_STREAM, 0);
    if (socket_return == -1) {
        perror("socket creation failed\n");
        return -1;
    } else {
        printf("socket created\n");
    }
    //empty the server address`
    bzero(&server_address, sizeof(server_address));

    server_address.sin_family = AF_INET;
    server_address.sin_addr.s_addr = htonl(INADDR_ANY);
    server_address.sin_port = htons(PORT);

    // binding socket
    bind_return = bind(socket_return, (struct sockaddr *)&server_address, sizeof(server_address));
    if (bind_return == -1) {
        perror("binding failed\n");
        close(socket_return);
        return -1;
    } else {
        printf("binding done\n");
    }

    // listening the socket
    listen_return = listen(socket_return, 5);
    if (listen_return == -1) {
        perror("listening failed");
        close(socket_return);
        return -1;
    } else {
        printf("server is  listening...\n");
    }

    socklen_t peer_address_len = sizeof(peer_address);
    // accept connection
    accept_return = accept(socket_return, (struct sockaddr *)&peer_address, &peer_address_len);
    if (accept_return == -1) {
        perror("accepting failed\n");
        close(socket_return);
        return -1;
    } else {
        printf("connection accepted\n");
    }
    char msg[MAX];
    while (1) {
        bzero(msg, sizeof(msg));

        // Read message
        ssize_t bytes_read = read(accept_return, msg, sizeof(msg) );
        if (bytes_read == 0) {
            printf("client disconnected\n");
            break;
        } else if (bytes_read < 0) {
            perror("failed to read message\n");
            break;
        }
        //displaying client message
        printf("From client: %s", msg);

    }

    // closing
    close(accept_return);
    close(socket_return);

    return 0;
}

客户端.c

/*
client.c
*/

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

#define MAX 256
#define PORT 8080

int main() {
    int socket_return, connect_return;
    struct sockaddr_in server_address;

    // Creating  socket
    socket_return = socket(AF_INET, SOCK_STREAM, 0);
    if (socket_return == -1) {
        printf("socket creation failed\n");
        return -1;
    } else {
        printf("socket created\n");
    }

    bzero(&server_address, sizeof(server_address));

    server_address.sin_family = AF_INET;
    server_address.sin_addr.s_addr = inet_addr("127.0.0.1");
    server_address.sin_port = htons(PORT);

    // Connecting the server
    connect_return = connect(socket_return, (struct sockaddr *)&server_address, sizeof(server_address));
    if (connect_return == -1) {
        printf("connection failed\n");
        close(socket_return);
        return -1;
    } else {
        printf("connected to server\n");
    }

    char msg[MAX];
    int i;

    while (1) {
        bzero(msg, sizeof(msg));
        printf("Enter string: ");
        i = 0;
        while ((msg[i++] = getchar()) != '\n');
        //when server detects the client message as 'exit' close the server
        if ((strncmp(msg, "exit", 4)) == 0) {
            printf("Exiting client\n");
            close(socket_return);
            break;
        }
        // sending message
        write(socket_return, msg, sizeof(msg));
        printf("You wrote %s\n",msg);
    }

    // close
    close(socket_return);

    return 0;
}

c sockets
1个回答
0
投票

要同时接受和处理多个客户端,您需要使用多线程的概念,例如 POSIX 线程库(pthreads)。

服务器

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>

#define PORT 8080
#define BUFFER_SIZE 1024

// Function to handle client communication
void *handle_client(void *client_socket) {
    int sock = *(int *)client_socket;
    char buffer[BUFFER_SIZE];
    int n;

    while ((n = recv(sock, buffer, sizeof(buffer) - 1, 0)) > 0) {
        buffer[n] = '\0'; // Null-terminate the received data
        printf("Client: %s\n", buffer);

        // Echo the received message back to the client
        send(sock, buffer, n, 0);
    }

    if (n == 0) {
        printf("Client disconnected\n");
    } else {
        perror("recv");
    }

    close(sock);
    free(client_socket);
    pthread_exit(NULL);
}

int main() {
    int server_fd, new_socket, *client_socket;
    struct sockaddr_in address;
    int addrlen = sizeof(address);
    pthread_t thread_id;

    // Creating socket file descriptor
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    // Setting up the address structure
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(PORT);

    // Binding the socket
    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
        perror("bind failed");
        close(server_fd);
        exit(EXIT_FAILURE);
    }

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

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

    while (1) {
        // Accepting new client connection
        if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0) {
            perror("accept");
            close(server_fd);
            exit(EXIT_FAILURE);
        }

        // Allocating memory for client socket descriptor
        client_socket = malloc(sizeof(int));
        *client_socket = new_socket;

        // Creating a new thread to handle the client
        if (pthread_create(&thread_id, NULL, handle_client, (void *)client_socket) < 0) {
            perror("pthread_create");
            close(new_socket);
            free(client_socket);
            continue;
        }

        // Detaching the thread so that it can clean up after itself
        pthread_detach(thread_id);
    }

    close(server_fd);
    return 0;
}

客户

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

#define PORT 8080
#define BUFFER_SIZE 1024

int main() {
    int sock;
    struct sockaddr_in server_address;
    char buffer[BUFFER_SIZE];
    char *message = "Hello from client";

    // Creating socket
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("socket creation error");
        exit(EXIT_FAILURE);
    }

    // Setting up the server address structure
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(PORT);

    // Convert IPv4 and IPv6 addresses from text to binary form
    if (inet_pton(AF_INET, "127.0.0.1", &server_address.sin_addr) <= 0) {
        perror("Invalid address / Address not supported");
        close(sock);
        exit(EXIT_FAILURE);
    }

    // Connecting to the server
    if (connect(sock, (struct sockaddr *)&server_address, sizeof(server_address)) < 0) {
        perror("Connection failed");
        close(sock);
        exit(EXIT_FAILURE);
    }

    // Sending a message to the server
    send(sock, message, strlen(message), 0);
    printf("Message sent\n");

    // Receiving a response from the server
    int n = recv(sock, buffer, sizeof(buffer) - 1, 0);
    if (n > 0) {
        buffer[n] = '\0'; // Null-terminate the received data
        printf("Server: %s\n", buffer);
    } else {
        perror("recv");
    }

    close(sock);
    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.