3月10号作业

C语言实现的UDP服务器,支持多客户端连接,消息广播功能。
摘要由CSDN通过智能技术生成
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>

#define MAX_CLIENTS 10
#define SERVER_PORT 12345
#define BUF_SIZE 1024

struct Client {
    struct sockaddr_in addr;
    int sockfd;
    char username[20];
};

struct Client clients[MAX_CLIENTS];
int num_clients = 0;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void *handle_client(void *arg) {
    struct Client *client = (struct Client *)arg;
    struct sockaddr_in client_addr = client->addr;
    char recv_buf[BUF_SIZE];
    int len;

    while (1) {
        len = recvfrom(client->sockfd, recv_buf, BUF_SIZE, 0, NULL, NULL);
        if (len > 0) {
            recv_buf[len] = '\0';
            // Broadcast message to all clients
            pthread_mutex_lock(&mutex);
            for (int i = 0; i < num_clients; i++) {
                if (sendto(clients[i].sockfd, recv_buf, strlen(recv_buf), 0,
                           (struct sockaddr *)&clients[i].addr,
                           sizeof(clients[i].addr)) == -1) {
                    perror("sendto");
                }
            }
            pthread_mutex_unlock(&mutex);
        }
    }
}

int main() {
    int sockfd;
    struct sockaddr_in server_addr;
    pthread_t tid;

    // Create socket
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    // Initialize server address structure
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(SERVER_PORT);

    // Bind socket to the server address
    if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) ==
        -1) {
        perror("bind");
        exit(EXIT_FAILURE);
    }

    printf("Server started. Waiting for clients...\n");

    while (1) {
        struct sockaddr_in client_addr;
        socklen_t addr_len = sizeof(client_addr);

        // Receive data from client
        char recv_buf[BUF_SIZE];
        int len = recvfrom(sockfd, recv_buf, BUF_SIZE, 0,
                           (struct sockaddr *)&client_addr, &addr_len);

        if (len > 0) {
            recv_buf[len] = '\0';
            // Add client to the list
            pthread_mutex_lock(&mutex);
            if (num_clients < MAX_CLIENTS) {
                clients[num_clients].addr = client_addr;
                clients[num_clients].sockfd = sockfd;
                strcpy(clients[num_clients].username, recv_buf);
                num_clients++;
                printf("Client '%s' joined the chat.\n", recv_buf);
                // Create a new thread to handle client's messages
                pthread_create(&tid, NULL, handle_client,
                               (void *)&clients[num_clients - 1]);
                pthread_detach(tid);
            } else {
                printf("Max clients reached. Connection rejected.\n");
            }
            pthread_mutex_unlock(&mutex);
        }
    }

    close(sockfd);
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值