首页 > 其他分享 >多线程实现高并发服务器

多线程实现高并发服务器

时间:2023-05-11 11:36:44浏览次数:37  
标签:info cnt addr int 并发 client 服务器 array 多线程

/*
    多线程实现并发服务器
        主线程负责接收
        子线程负责处理

*/

#include <stdio.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <wait.h>
#include <signal.h>
#include <errno.h>
#include <pthread.h>

struct sockInfo{
    int cfd, cnt;
    pthread_t tid;
    struct sockaddr_in client_addr;
};

struct sockInfo info_array[128];

void *callback(void *arg)
{
    int id = *(int *) arg;
    char clientIP[16];
    inet_ntop(AF_INET, (void *)&info_array[id].client_addr.sin_addr.s_addr, clientIP, sizeof(clientIP));
    unsigned short clientPORT = ntohs(info_array[id].client_addr.sin_port);

    printf("client ip is %s, port is %d\n", clientIP, clientPORT);
    char recvBuf[1024] = {0};
    int recvlen = read(info_array[id].cfd, recvBuf, sizeof(recvBuf));
    if(recvlen == -1)
    {
        perror("read");
        exit(-1);
    }
    else if(recvlen == 0)
    {
        printf("客户端断开连接······\n");
        // 如果循环发送接收,这个地方要加 break
    }
    else
    {
        printf("recv client data: %s\n", recvBuf);
    }


    // 给客户端发送数据
    char *data = "hello, i am server";

    int len = write(cfd, data, strlen(data));
    if(len == -1)
    {
        perror("write");
        exit(-1);
    }
    return NULL;
}


int main()
{

    
    
    sigaction(SIGCHLD, &act, NULL);

    int lfd = socket(AF_INET, SOCK_STREAM, 0);
    if(lfd == -1)
    {
        perror("socket");
        exit(-1);
    }

    char *temp = "192.168.248.128";
    int inet_ip;
    struct sockaddr_in saddr;
    saddr.sin_family = AF_INET;
    inet_pton(AF_INET, temp, (void *) &inet_ip);
    saddr.sin_addr.s_addr = inet_ip;
    saddr.sin_port = htons(9999);
    int ret = bind(lfd, (struct sockaddr *) &saddr, sizeof(saddr));
    if(ret == -1)
    {
        perror("bind");
        exit(-1);
    }
    ret = listen(lfd, 5);
    if(ret == -1)
    {
        perror("listen");
        exit(-1);
    }
    int info_cnt = 0;
    while(1)
    {
        struct sockaddr_in client_addr;
        int client_addr_len = sizeof(client_addr);
        int cfd = accept(lfd, (struct sockaddr *) &client_addr, (void *) &client_addr_len);
        if(cfd == -1)
        {
            if(errno == EINTR)
                continue;
            perror("accept");
            exit(-1);
        }
        // struct sockInfo info;
        // info.cfd = cfd;
        // // info.client_addr = client_addr; // 结构体不能直接赋值结构体
        // memcpy(info.client_addr, client_addr, sizeof(client_addr));
        info_array[info_cnt].cfd = cfd;
        memcpy(info_array[info_cnt].client_addr, client_addr, sizeof(client_addr));
        info_array[info_cnt].cnt = info_cnt;

        pthread_create(&info_array[info_cnt].tid, NULL, callback, (void *) &info_array[info_cnt].cnt);
        pthread_detach(new_thread);
        info_cnt++;
        if(info_cnt == sizeof(info_array)) / sizeof(info_array[0]);
            break;
    }
    sleep(1);

    for(int i = 0; i < info_cnt; i++)
        close(info_array[i]->cfd);
    close(lfd);



    return 0;
}

 

标签:info,cnt,addr,int,并发,client,服务器,array,多线程
From: https://www.cnblogs.com/WTSRUVF/p/17390542.html

相关文章

  • java线程池和多线程的使用详解
    Java多线程和线程池使用java多线程实现的几种方法1.继承Thread类继承Thread类,重写run方法,创建线程类对象调用start方法启动线程。publicclassThreadDemo{/***继承Thread类创建线程*/publicstaticclassMyThreadextendsThread{publ......
  • 免费云服务器
    作为一枚白嫖党的程序员,因为囊肿羞涩,只能白嫖一些大厂商的云服务器。看了一下阿里云和腾讯云,发现他们并没有啥可以白嫖的,因为这些大厂商给的福利只要30天,到期了我又要从新安装环境和配置服务等等操作。在贴吧中,我发现了一个可以长期免费白嫖而且性价比非常高的云服务厂商,那就是阿......
  • expect脚本实现ssh自动登录远程服务器
    使用expect脚本可以实现SSH自动登录远程服务器。下面是一个简单的示例:首先,需要安装expect软件包,可以在Ubuntu或其他Linux发行版中使用以下命令安装:1sudoapt-getupdate2sudoapt-getinstallexpect然后,编写expect脚本,该脚本将模拟SSH连接远程服务器并登......
  • 公共DNS服务器IP地址
    国内阿里IPv4223.5.5.5223.6.6.6IPv62400:3200::12400:3200:baba::1腾讯IPv4119.29.29.29百度IPv4180.76.76.76IPv62400:da00::6666114国外Google8.8.8.88.8.4.4最后编辑时间:2023年5月10日21:35:39......
  • 华为2288H V5服务器安装PVE
    获取PVE文件,存储到本地进入华为BMC管理系统点击远程控制点击HTML集成远程控制点击系统启动项点击软驱重启系统Xorg-configurecp/xorg.conf.new/etc/X11/xorg.confvi/etc/X11/xorg.confChangeDriverfrom"modeset"to"fbdev"startx余下步......
  • 主机服务器tmp目录报php病毒木马的解决方法
    Linux和Windows主机的tmp目录都是临时文件存放的目录,比如程序运行产生的临时文件和用户上传的临时文件都会在这个目录生成。有时候这个目录会产生病毒或木马程序,大部分都php病毒木马,这种情况一般是黑客利用网站程序漏洞上传了php病毒木马,或者是因为php.ini里面的upload_tmp_dir配......
  • 假设知道服务器IP,如何查询它绑定的域名?
    在一些场景中,我们往往只得到了一个IP地址,那么如何通过IP地址快速地找到它绑定的域名呢?1、IP历史解析记录输入查询的IP地址,获取IP绑定过的域名记录。ip138查询:https://site.ip138.com/2、同站/旁站查询关键词:IP反查域名、同IP网站查询、旁站查询,通过一些在线查询工具获取域名。IP反......
  • Linux系统下Samba服务器的配置
    第1步:将目录/home/media设置为允许所有用户访问,但仅允许用户mary具有修改该目录的权限。其配置步骤简述如下。第2步:将目录/var/samba/student设置为只允许student组的成员访问,student组中有stu01、stu02·····stu05,共5个成员。配置步骤简述如下。第3步:用testparm命令测试......
  • Linux系统下NFS服务器的配置
    第1步:NFS规划。1)将本地文件系统的/home/mp3目录共享,mary客户机对该目录具有读写限权,其他所有用户对该目录具有只读限权。 2)将本地文件系统的/home/vedio目录共享,192.168.21.100与192.168.21.200两个客户机对该目录具有读写限权,而192.168.21.0、24网段内的其他客户机对该目录......
  • 集合的并发修改异常
    情景一:ArrayList<Integer>arrayList=newArrayList<>();for(inti=0;i<10_000;i++){ arrayList.add(newRandom().nextInt(100_000_000));}/**开启多个线程,每个线程都执行迭代器*/for(inti=0;i<20;i++){ newThread(()->{ Iterator<......