Linux网络编程 -- 服务器-- 多线程实现多用户

server.c

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

#include "wrap.h"

#define SERV_PORT 8888

struct clie_info
{
    struct sockaddr_in clie_addr;
    int connfd;
};

void *read_msg(void *arg);

int main()
{
    int i = 0;
    int opt = 1;
    int listenfd, cfd;   //文件描述符
    socklen_t clie_addr_len;
    struct sockaddr_in serv_addr, clie_addr;

    pthread_t tid;      //线程
    struct clie_info thread_clie[256];      //根据最大线程数创建结构体数组.

    //参数1: AF_INET ->ipv4 AF_INET6 ->ipv6 
    //参数2:SOCK_STREAM -> TCP SOCK_DGRAM -> UDP
    //参数3:传0 表示使用默认协议。
    listenfd = Socket(AF_INET, SOCK_STREAM, 0);


    //端口复用
    setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

    bzero(&serv_addr, sizeof(serv_addr));  
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(SERV_PORT);  //主机字节序转换为网络字节序  大端模式 小端模式
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); //网络地址为INADDR_ANY,这个宏表示本地的任意IP地址
    Bind(listenfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));   //由于历史原因,需强制转换为 struct sockaddr * 类型

    Listen(listenfd, 128);  //设置同一时刻链接服务器上限数

    while (1)
    {
        clie_addr_len = sizeof(clie_addr);
        cfd = Accept(listenfd, (struct sockaddr *)&clie_addr, &clie_addr_len);


        thread_clie[i].clie_addr = clie_addr;
        thread_clie[i].connfd = cfd;
        //当有客户端连接 就创建一个线程
        pthread_create(&tid, NULL, read_msg, (void *)&thread_clie[i]);
        pthread_detach(tid);

        i++;
    }    

    return 0;
}

void *read_msg(void *arg)
{
    int i, n;
    char buf[BUFSIZ];       //存放读取到的客户端的数据
    char clie_IP[INET_ADDRSTRLEN];   //用来存放客户端IP
    struct clie_info *thread_clie = (struct clie_info *)arg;

    while (1)
    {
        n = Read(thread_clie->connfd, buf, sizeof(buf));
        if (0 == n)
        {
            printf("Client %d closed\n", thread_clie->connfd);
            break;
        }

        printf("Client IP: %s, Port: %d\n",
        inet_ntop(AF_INET, &(*thread_clie).clie_addr.sin_addr.s_addr, clie_IP, sizeof(clie_IP)),
        ntohs((*thread_clie).clie_addr.sin_port));

        for (i = 0; i < n; ++i)
        {
            buf[i] = toupper(buf[i]);
        }

        Write(thread_clie->connfd, buf, n);
    }

    Close(thread_clie->connfd);

    return (void *)0;
}

猜你喜欢

转载自blog.csdn.net/Zhoujy1996/article/details/81431511
今日推荐