zoukankan      html  css  js  c++  java
  • C语言socket编程--每日签到

      前几天写了个python的每日签到,你运行还得借助crontab,很是不爽.....正好前几天看了个关于c编写daemon进程,加上自己那点可怜的socket知识,于是我们重操旧页,C语言版的每日签到。就是要签到~~~

      关于daemon程序,也叫守护进程,一般运行在后台,我喜欢悄悄的运行。。。。哈哈哈,这个init_daemon.c被大家在网上转来转去,原则都是一样的

    Daemon程序设计主要原则包括:

    (1)       程序运行后调用fork,并让父进程退出。子进程获得一个新的进程ID,但继承了父进程的进程组ID。

    (2)       调用setsid创建一个新的session,使自己成为新session和新进程组的leader,并使进程没有控制终端(tty)。

    (3)       设置文件创建mask为0,避免创建文件时权限的影响。

    (4)       关闭不需要的打开文件描述符。因为Daemon程序在后台执行,不需要于终端交互,通常就关闭STDIN、STDOUT和STDERR。其它根据实际情况处理。

    (5)       Daemon无法输出信息,可以使用SYSLOG或自己的日志系统进行日志处理。(可选)

    (6)       编写管理Daemon的SHELL脚本,使用service对Daemon进行管理和监控。(可选)

      

    #include <unistd.h>
    #include <signal.h>
    #include <sys/param.h>
    #include <sys/stat.h>
    void init_daemon(void)
    {
        int pid;
        int i;
    
        if(pid=fork())
            exit(0);//是父进程,结束父进程
        else if(pid< 0)
            exit(1);//fork失败,退出
       //是第一子进程,后台继续执行
        
        setsid();//第一子进程成为新的会话组长和进程组长
        //并与控制终端分离
        if(pid=fork())
        exit(0);//是第一子进程,结束第一子进程
        else if(pid< 0)
        exit(1);//fork失败,退出
        //是第二子进程,继续
       //第二子进程不再是会话组长
        
        for(i=0;i< NOFILE;++i)//关闭打开的文件描述符
        close(i);
        chdir("/tmp");//改变工作目录到/tmp
        umask(0);//重设文件创建掩模
        return;
    }

    这个其实就是个引子,下面的是实体。。

    #include <stdio.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <time.h>
    #include <errno.h>
    #include <signal.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/wait.h>
    #include <sys/time.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    
    #define IPSTR "1.1.1.1"
    #define PORT 80
    #define BUFSIZE 1024
    
    void init_daemon(void); //守护进程初始化
    int main(int argc, char **argv)
    {
        FILE *fp;
        time_t t;
        int sockfd, ret, i, h;
        struct sockaddr_in servaddr;
        /*
          sockaddr_in(在netinet/in.h中定义):
          struct sockaddr_in{
          short sin_family;/*地址族一般来说是 AF_INET
          unsigned short sin_port; /* Port number(必须采用网络数据格式,普通数字可以用htons()转换成网络格式的数字)
          }
        */
        char str1[4096], str2[4096], buf[BUFSIZE], *str;
        socklen_t len;
        fd_set   t_set1;
        struct timeval  tv;
        /*
          struct timeval{
              time_t  tv_sec; //seconds
              suseconds_t tv_usec; // 毫米 microseconds
          }
         */
        init_daemon(); //守护进程初始化
        while(1){
            if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
                printf("创建网络连接失败,本线程即将终止---socket error!
    ");
                exit(0);
            };
            /*填写sockadd_in结构*/
            bzero(&servaddr, sizeof(servaddr));
            servaddr.sin_family = AF_INET;
            servaddr.sin_port = htons(PORT);
            if (inet_pton(AF_INET, IPSTR, &servaddr.sin_addr) <= 0 ){
                //inet_pton 将点分十进制IPSTR转换成一个16进制地址,转换错误返回0
                /*另一种填写servaddr.sin_addr.addr = inet_addr(IPSTR);*/
                printf("地址错误--inet_pton error!
    ");
                exit(0);
            };
            /*尝试连接*/
            if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0){
                printf("连接到服务器失败,connect error!
    ");
                exit(0);
            }
            //printf("与远端建立了连接
    ");
            //发送数据
            memset(str2, 0, 4096); 
            //memset(void *s, int c, size_t n)将参数s的内存前n个字符串用参数c填入,常用做内存控件初始化
            strcat(str2, "qdxq=kx&qdmode=1&todaysay=love+is+beautiful.so+beautiful&fastreply=1");
            str=(char *)malloc(128);
            len = strlen(str2);
            sprintf(str, "%d", len);
            
            memset(str1, 0, 4096);
            strcat(str1, "POST http://xxx.xxx.com/plugin.php?identifier=dps_sign&module=sign&operation=qiandao&infloat=1&inajax=1 HTTP/1.1
    ");
            strcat(str1, "Host: xxx.xxxx.com
    ");
            strcat(str1, "Content-Type: application/x-www-form-urlencoded
    ");
            strcat(str1, "User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.114 Safari/537.36
    ");
            strcat(str1, "Cookie:你的cookie
    ");
            strcat(str1, "Content-Length: ");
            strcat(str1, str);
            strcat(str1, "
    
    ");
            
            strcat(str1, str2);
            strcat(str1, "
    
    ");
            // printf("%s
    ",str1);
            
            ret = write(sockfd,str1,strlen(str1));
            /*  write(int fd, const void *buf, size_t count)*/
            if (ret < 0) {
                printf("发送失败!错误代码是%d,错误信息是'%s'
    ",errno, strerror(errno));
                exit(0);
            }else{
                 //printf("消息发送成功,共发送了%d个字节!
    
    ", ret);
            }
            /*接受从server端传来的信息*/
            //FD_ZERO(&t_set1); //清空套接字集合
            //FD_SET(sockfd, &t_set1); //将sockfd加入t_set1集合中
            //对fd_set还有种常见用法FD_CLR(fd,&set)将fd从集合中清楚
            // printf("%d",sizeof(t_set1));exit(0); result:128Byte = 128*8个fd
            //可监控的fd个数取决于sizeof(fd_set)
            /*
              while(1){
                  sleep(2);
                  tv.tv_sec = 0;
                  tv.tv_usec = 0;
                  h = 0;
                  h = select(sockfd +1, &t_set1, NULL, NULL, &tv);
                  //printf("
    %d",h);exit(0); //results:1
              
                 //if (h == 0) continue;
                 if (h < 0) {
                      close(sockfd);
                      printf("在读取数据报文时SELECT检测到异常,该异常导致线程终止!
    ");
                      return -1;
                  };
              
                  if (h > 0){
                  memset(buf, 0, 4096);
                  i= read(sockfd, buf, 4095);
                  if (i == 0){
                      close(sockfd);
                  printf("读取数据报文时发现远端关闭,该线程终止!
    ");
                  return -1;
               }
              
               printf("%s
    ", buf);
             }
            
             }*/
            close(sockfd); 
            // return 0;
            /*写入日志*/
            
            if((fp=fopen("sign.log","a"))>=0){
                t = time(0);
                fprintf(fp, "l137 was here at %s", asctime(localtime(&t)));
                fclose(fp);
            }
            sleep(14400); //每四个小时签到,妈妈再也不担心,今天没签到了
        }
        return 0;
    }

    具体的请求你可以用burp抓个提交包,然后把你的cookie对应的填进去。。http就是一种特殊的socket,大家商量了一下,你用80端口,我也80端口,你按照这个格式发数据,OK,我按照说好的格式解析数据。。。。。

    编译的时候gcc -g init_daemon.c bbs_sign.c -o l137

    当然我们也可以自己写一个简单的Makefile,简洁大方上档次。。

    CC = gcc
    all:myapp
    
    myapp: 
        $(CC) -g init_daemon.c bbs_sign.c -o l137
    clean:
        rm -rf  l137

    找个小服务器跑下,小程序安安稳稳的运行在后台。。。。。

        

  • 相关阅读:
    poj 2100 尺取法 一个数字拆成连续数字平方和
    poj 1011 dfs+剪枝
    CF-242-C bfs+stl
    hdu 1297 递推
    poj 2104 划分树模板
    poj 3842 全排列+筛素数+暴力
    hdu 1421 经典dp
    hdu 1069 最长上升子序列变形
    hdu 3496 二维费用的01背包
    nyoj 16 最长上升子序列变形
  • 原文地址:https://www.cnblogs.com/l137/p/3407164.html
Copyright © 2011-2022 走看看