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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值