• 作业-11.24


    1、多线程并发服务器

    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include

    #define ERRLOG(msg) do{\
                    printf("%s:%s:%d\n", __FILE__, __func__, __LINE__);\
                    perror(msg);\
                }while(0)

    #define N 128

    typedef struct _MSG{
        int acceptfd;
        struct sockaddr_in clientaddr;
    }msg_t;

    void *deal_read_write(void *arg)
    {
        msg_t msg = *(msg_t *)arg;
        printf("客户端[%s:%d]连接到服务器..\n", inet_ntoa(msg.clientaddr.sin_addr), ntohs(msg.clientaddr.sin_port));
        int nbytes = 0;
        char buff[N] = {0};
        while(1)
        {
            memset(buff, 0, N);
            if(-1 == (nbytes = recv(msg.acceptfd, buff, N, 0)))
            {
                perror("recv");
                break;
            }
            else if(!nbytes)
            {
                printf("客户端[%s:%d]断开了连接..\n", inet_ntoa(msg.clientaddr.sin_addr), ntohs(msg.clientaddr.sin_port));
                break;
            }
            if(!strncmp(buff, "quit", 4))
            {
                printf("客户端[%s:%d]退出了..\n", inet_ntoa(msg.clientaddr.sin_addr), ntohs(msg.clientaddr.sin_port));
                break;
            }
            printf("客户端[%s:%d]发来数据[%s]\n", inet_ntoa(msg.clientaddr.sin_addr), ntohs(msg.clientaddr.sin_port), buff);
            strcat(buff, "-->\n");
            if(-1 == send(msg.acceptfd, buff, N, 0))
            {
                perror("send");
               break;
            }
        }
        close(msg.acceptfd);
        pthread_exit(NULL);
    }

    int main(int argc, const char *argv[])
    {
        if(3 != argc)
        {
            printf("Usage : %s \n", argv[0]);
            exit(-1);
        }

        int sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if(-1 == sockfd)
        {
            ERRLOG("socket");
            return -1;
        }

        struct sockaddr_in serveraddr;
        memset(&serveraddr, 0, sizeof(serveraddr));
        serveraddr.sin_family = AF_INET;
        serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
        serveraddr.sin_port = htons(atoi(argv[2]));

        socklen_t serveraddr_len = sizeof(serveraddr);

        if(-1 == bind(sockfd, (struct sockaddr *)&serveraddr, serveraddr_len))
        {
            ERRLOG("bind");
            return -1;
        }

        if(-1 == listen(sockfd, 5))
        {
            ERRLOG("listen");
            return -1;
        }

        struct sockaddr_in clientaddr;
        memset(&clientaddr, 0, sizeof(clientaddr));
        socklen_t clientaddr_len = sizeof(clientaddr);

        int acceptfd = 0;
        pthread_t tid = 0;
        msg_t msg;
         int err_code = 0;

        while(1)
        {
            if(-1 == (acceptfd = accept(sockfd, (struct sockaddr *)&clientaddr, &clientaddr_len)))
            {
                ERRLOG("accept");
                return -1;
            }
            msg.acceptfd = acceptfd;
            msg.clientaddr = clientaddr;
            if(0 != (err_code  = pthread_create(&tid, NULL, deal_read_write, &msg)))
            {
                printf("pthread_create error %s\n", strerror(err_code));
                return -1;
          }
            if(0 !=  (err_code = pthread_detach(tid)))
            {
                printf("pthread_detach error %s\n", strerror(err_code));
                return -1;
          }
        }

        close(sockfd);

        return 0;
    }

     

    2、多进程并发服务器

    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include

    #define ERRLOG(msg) do{\
                    printf("%s:%s:%d\n", __FILE__, __func__, __LINE__);\
                    perror(msg);\
                }while(0)

    #define N 128

    void sig_function()
    {
        wait(NULL);
    }

    int main(int argc, const char *argv[])
    {
        if(3 != argc)
        {
            printf("Usage : %s \n", argv[0]);
            return -1;
        }

        int sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if(sockfd < 0)
        {
            ERRLOG("socket");
            return -1;
        }

        struct sockaddr_in serveraddr;
        memset(&serveraddr, 0, sizeof(serveraddr));
        serveraddr.sin_family = AF_INET;
        serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
        serveraddr.sin_port = htons(atoi(argv[2]));

        socklen_t serveraddr_len = sizeof(serveraddr);

        if(bind(sockfd, (struct sockaddr *)&serveraddr, serveraddr_len) < 0)
        {
            ERRLOG("bind");
            return -1;
        }

        if(listen(sockfd, 5) < 0)
        {
            ERRLOG("listen");
            return -1;
        }

        signal(SIGUSR1, sig_function);

        struct sockaddr_in clientaddr;
        memset(&clientaddr, 0, sizeof(clientaddr));
        socklen_t clientaddr_len = sizeof(clientaddr);

        int acceptfd = 0;
        pid_t pid = 0;

        while(1)
        {
            if((acceptfd = accept(sockfd, (struct sockaddr *)&clientaddr, &clientaddr_len)) < 0)
            {
                ERRLOG("accept");
                return -1;
            }

            if((pid = fork()) < 0)
            {
                ERRLOG("fork");
                return -1;
            }
            else if(!pid)
            {
                printf("客户端[%s:%d]连接到服务器..\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
                int nbytes = 0;
                char buff[N] = {0};
                while(1)
                {
                    memset(buff, 0, N);
                    if((nbytes = recv(acceptfd, buff, N, 0)) < 0)
                    {
                        ERRLOG("recv");
                        return -1;
                    }
                    else if(!nbytes)
                    {
                        printf("客户端[%s:%d]断开了连接..\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
                        break;
                    }
                    if(!strncmp(buff, "quit", 4))
                    {
                        printf("客户端[%s:%d]退出了..\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
                        break;
                    }
                    printf("客户端[%s:%d]发来数据[%s]\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port), buff);
                    strcat(buff, "--hqyj");
                    if(send(acceptfd, buff, N, 0) < 0)
                    {
                        ERRLOG("send");
                        return -1;
                    }
                }
                close(acceptfd);
                kill(getppid(), SIGUSR1);
                return 0;
            }
            else if(pid > 0)
            {
                close(acceptfd);
            }
        }

        close(sockfd);

        return 0;
    }

     

     

    3、fttp下载上传

    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include

    #define ERR_MSG(msg) do{\
        fprintf(stderr, "__%d__:", __LINE__);\
        perror(msg);\
    }while(0)

    int do_download(int sfd, struct sockaddr_in sin);
    int do_upload(int sfd, struct sockaddr_in sin);

    int main(int argc, const char *argv[])
    {
        if(argc != 3)
        {
            printf("please--> %s \n", argv[0]);
            return -1;
        }

        int sfd = socket(AF_INET, SOCK_DGRAM, 0);
        if(sfd < 0)
        {
            ERR_MSG("socket");
            return -1;
        }

        struct sockaddr_in sin;
        sin.sin_family      = AF_INET;      
        sin.sin_port        = htons(atoi(argv[2]));  
        sin.sin_addr.s_addr = inet_addr(argv[1]);

        char c = 0;
        int flag = 1;
        while(1)
        {
            system("clear");
            printf("**********************\n");
            printf("*******1.下载*********\n");
            printf("*******2.上传*********\n");
            printf("*******3.退出*********\n");
            printf("**********************\n");
            printf("请输入>>>");

            c = getchar();
            while(getchar()!=10);

            switch(c)
            {
            case '1':
                do_download(sfd, sin);
                break;
            case '2':
                do_upload(sfd, sin);
                break;
            case '3':
                flag = 0;
                break;
            default:
                printf("输入错误,请重新输入\n");
            }

            if(!flag)
            {
                break;
            }
            printf("输入任意字符清屏>>>");
            while(getchar() !=10);
        }


        close(sfd);
        return 0;
    }

    int do_download(int sfd, struct sockaddr_in sin)
    {
        char filename[20] = "";
        char buf[516] = "";

        bzero(buf, sizeof(buf));
        printf("请输入要下载的文件名>>>");
        fgets(filename, sizeof(filename), stdin);
        filename[strlen(filename)-1] = 0;

        int size = sprintf(buf, "%c%c%s%c%s%c", 0, 1, filename, 0, "octet", 0);
        if(sendto(sfd, buf, size, 0, (struct sockaddr*)&sin, sizeof(sin)) < 0)
        {
            ERR_MSG("sendto");
            return -1;
        }

        int fd = -1, flag = 0;    
        socklen_t addrlen = sizeof(sin);
        ssize_t res = 0;

        unsigned short num = 0;     

        while(1)
        {
            bzero(buf, sizeof(buf));
            res = recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&sin, &addrlen);
            if(res < 0)
            {
                ERR_MSG("recvfrom");
                return -1;
            }

            if(3 == buf[1])
            {
                if(htons(num+1) == *(unsigned short*)(buf+2))
                {
                    num++;

                    if(0 == flag)
                    {
                        fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0664);
                        if(fd < 0)
                        {
                            ERR_MSG("open");
                            return -1;
                        }
                        flag = 1;
                    }

                    if(write(fd, buf+4, res-2-2) < 0)
                    {
                        ERR_MSG("write");
                        return -1;
                    }

                    buf[1] = 4;
                    if(sendto(sfd, buf, 4, 0, (struct sockaddr*)&sin, sizeof(sin)) < 0)
                    {
                        ERR_MSG("sendto");
                        return -1;
                    }

                    if(res-2-2 < 512)
                    {
                        printf("%s 文件下载完毕\n", filename);
                        break;
                    }
                }
            }
            else if(5 == buf[1])
            {
                fprintf(stderr, "错误码:%d 错误信息:%s\n", ntohs(*(unsigned short*)(buf+2)), buf+4);
                break;
            }
        }

        close(fd);
        return 0;
    }

    int do_upload(int sfd, struct sockaddr_in sin)
    {
        char str[1000] = "";
        char *ptr = str;
        short int *ptr1 = (short int*)ptr;
        *ptr1 = htons(2);
        char *ptr2 = ptr+2;

        char filename[128] = "";
        printf("请输入要上传的文件名>>>");
        scanf("%s",filename);
        getchar();
        strcpy(ptr2,filename);

        char *ptr3 = ptr2+strlen(ptr2)+1;
        strcpy(ptr3,"octet");

        int size = 2+strlen(ptr2)+1+strlen(ptr3)+1;
        if(sendto(sfd, str, size, 0, (struct sockaddr*)&sin, sizeof(sin)) < 0)
        {
            ERR_MSG("sendto");
            return -1;
        }
        printf("sendto success\n");

        char str1[6] = "";                  
        struct sockaddr_in rcv_addrmsg;
        socklen_t addrlen = sizeof(rcv_addrmsg);


        if(recvfrom(sfd,str1,sizeof(str1),0,(struct sockaddr*)&rcv_addrmsg,&addrlen) < 0)
        {
            ERR_MSG("recvfrom");
            return -1;
        }

        int fd = open(filename,O_RDONLY);
        if(fd<0)
        {
            ERR_MSG("open");
            return -1;
        }

        short int num = 1;                       
        char str2[1024] = "";


        ssize_t rts = 0;
        while(1)
        {
            char *sjb = str2;
            short int *sjb1 = (short int*)sjb;
            *sjb1 = htons(3);

            short int *sjb2 = (short int*)(sjb+2);
            *sjb2 = htons(num);

            char *sjb3 = (str2+4);

            rts = read(fd,sjb3,512);
            int sjblen = rts+4;

            if(sendto(sfd,str2,sjblen,0,(struct sockaddr*)&rcv_addrmsg,addrlen) < 0)
            {
                ERR_MSG("sendto");
                return -1;
            }

            bzero(str1,sizeof(str1));
            if(recvfrom(sfd,str1,sizeof(str1),0,(struct sockaddr*)&rcv_addrmsg,&addrlen) < 0)
            {
                ERR_MSG("recvfrom");
                return -1;
            }

            char *ack = str1;
            short int *err;
            err = (short int*)ack;
            if(ntohs(*err) == 5)
            {
                printf("error:%s\n",(char*)(err+2));
                return -1;
            }

            short int *kbh = (short int*)str1;
            if(ntohs(*(kbh+1)) != num)
            {
                continue;
            }

            num++;

            if(rts != 512)
            {
                printf("send file success!\n");
                break;
            }

        }
    }

            下载

     

            上传

                    上传前

                     上传后

                     终端

     

  • 相关阅读:
    Allegro如何导出器件坐标文件
    Java“实战”问题三连,你面试时遇到了吗?冲刺大厂面试
    融合差分进化和混合多策略的麻雀搜索算法
    智能驾驶ADAS算法设计及Prescan仿真(3): 自适应巡航ACC跟车目标选择策略设计与simulink仿真
    VMware添加Ubuntu虚拟机-Ubuntu系统的安装-物联网开发
    tx-前端笔试题记录
    JAVA多线程基础篇-关键字synchronized
    leetcode写题笔记 -- 罗马数字转整数
    Linux--多线程(一)
    Flowable 中的网关、流程变量以及历史流程
  • 原文地址:https://blog.csdn.net/MisakaMikotto/article/details/128027025