June 9th Tuesday (六月 九日 火曜日)

来源:互联网 发布:程序员 工作描述 编辑:程序博客网 时间:2024/04/28 03:05


  I am going to put C++ aside.  In the future, it is not main my program language.  Maybe, I will use it to write some tools.

  The last program is following.

//herald.cpp
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <sys/stat.h>
//#include <pthread.h>

//const
//#define PATH_MAX           (256)
#define HERALD_SERV        "Herald"
#define HERALD_SERV_PORT   (8888)
#define BUFFER_MAX         (1024)

//class
class From {
private:
    size_t dest_len;
    char dest[PATH_MAX];
    size_t msg_len;
    unsigned char *msg;
   
    int socket_recv;
   
public:
    From ()  : dest_len(0), msg_len(0), msg(NULL) {
        memset(dest, 0, sizeof(dest));
    }
   
    int CreateReceiveSocket() {
        int ret = 0;
        struct sockaddr_in addr_in;
        struct servent *serv = NULL;
       
        socket_recv = socket(AF_INET, SOCK_DGRAM, 0);
        memset(&addr_in, 0, sizeof(addr_in));
        addr_in.sin_family = AF_INET;

        serv = getservbyname(HERALD_SERV, "udp");
        if(serv != NULL){
            addr_in.sin_port = serv->s_port;
        }
        else{
            addr_in.sin_port = htons(HERALD_SERV_PORT);
            fprintf(stdout, "Can't get Herald Server Port. Now, default port(%d) is used./n", addr_in.sin_port);
        }
        addr_in.sin_addr.s_addr = INADDR_ANY;
        ret = bind(socket_recv, (struct sockaddr *)&addr_in,sizeof(addr_in));

        return ret;
    }
   
    int ParseMsg(const unsigned char *buf, size_t buf_len) {
        int ret = 0;
       
        memset(dest, 0, sizeof(dest));
       
        if (buf) {
           
            dest_len = (size_t)buf[0];
            msg_len = (size_t)buf[dest_len + 1];
           
            if ((dest_len + msg_len) == buf_len) {
                memcpy(dest, &buf[1], dest_len);
                msg = (unsigned char *)malloc(sizeof(unsigned char) * msg_len);
                if (msg) {
                    memcpy(msg, &buf[dest_len + 2], msg_len);
                    ret = 1;
                }
            }
           
        }
       
        return ret;
    }
   
    int Receive() {
        int                ret = 0;
        long               recv_len = 0;
        struct sockaddr_in sock_addr;
        socklen_t          siz_addr = 0;
        unsigned char buffer[BUFFER_MAX];

        memset(&sock_addr, 0, sizeof(sock_addr));
        memset(buffer, 0, sizeof(buffer));
        siz_addr = sizeof( sock_addr );
       
        recv_len = recvfrom( socket_recv, buffer, sizeof(buffer), 0, (struct sockaddr *)&sock_addr, &siz_addr );
        if (recv_len != -1) {
            ret = ParseMsg(buffer, recv_len);
        }
       
        return ret;
    }
   
    const size_t getDestLength() const {
        return dest_len;
    }
   
    const char * getDest() const {
        return dest;
    }
   
    const size_t getMsgLength() const {
        return msg_len;
    }
   
    const unsigned char * getMsg() const {
        return msg;
    }
   
    ~From() {
        if (msg)
            free(msg);
        close(socket_recv);
    }
};

class To {
private:
    int socket_snd;
public:
    To() {
        socket_snd = socket(AF_UNIX, SOCK_DGRAM, 0);
    }
   
    int Send(const unsigned char *msg, const size_t msg_len, const char *dest, const size_t dest_len) {
        int ret = 0;
        int snd_len = 0;
        struct sockaddr_un sockaddr;
       
        memset(&sockaddr, 0, sizeof(sockaddr));
        sockaddr.sun_family = AF_UNIX;
        strncpy((char *)&sockaddr.sun_path, dest, dest_len);
        snd_len = sendto(socket_snd, (const void *)msg, msg_len, 0, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
        if (snd_len != -1) {
            ret = 1;
        }
       
        return ret;
    }
   
    ~To() {
        close(socket_snd);
    }
};

//signal
int gEndFlag = 0;
struct sigaction g_old_term;
struct sigaction g_old_int;

void endup_signal(int sig, siginfo_t *siginfo, void *parm){
    gEndFlag = 1;
}

//exit
void restore_sigact() {
    sigaction(SIGTERM, &g_old_term, NULL);
    sigaction(SIGINT, &g_old_int, NULL);
}

//main
int main() {
    struct sigaction usr_action;
    sigset_t block_mask;

    //signal register
    sigfillset(&block_mask);
    usr_action.sa_sigaction = endup_signal;
    usr_action.sa_mask = block_mask;
    usr_action.sa_flags = SA_SIGINFO;
   
    memset(&g_old_term, 0, sizeof(struct sigaction));
    memset(&g_old_int, 0, sizeof(struct sigaction));
   
    sigaction(SIGTERM, &usr_action, &g_old_term);
    sigaction(SIGINT, &usr_action, &g_old_int);
   
    From from;
    To to;
   
    if (from.CreateReceiveSocket()) {
   
        while (!gEndFlag) {
           
            if (from.Receive()) {
               
                if (to.Send(from.getMsg(), from.getMsgLength(), from.getDest(), from.getDestLength()) == 0) {
                    fprintf(stdout, "Error: dest = %s/n",  from.getDest());
                }
            }
        } //while
    }
    else
        fprintf(stdout, "Can't bind received socket./n");
   
    return 0;
}