尝试为Windows开发简单/小型syslog服务器。
此实现只是将来自同一机器的其他2个进程的LOGS存储在同一机器中。

希望这类似于LINUX的实现。开始使用UDP DATAGRAM在进程之间发送数据。

它按预期工作。但是,已经注意到,拔下NETWORK电缆时,消息不会从客户端进程应用程序到达服务器。

客户端进程报告10049错误(拔出网络电缆时)
请求一些指导,以使如何在本地过程之间进行这项工作。从那以后,我所有的过程都在本地计算机上运行。

服务器端监听代码:

int main(int argc,char *argv[])
{
    SOCKET s;
    FILE *fp;
    struct sockaddr_in server, si_other;
    int slen , recv_len;
    char buf[BUFLEN];
    WSADATA wsa;
    struct stat sts;
    char fileNameWithPath[512]={'\0'};
    int status;

    printf("ARGC %d\n",argc);
    char a[10];
    strcpy(logBasePath,"C:\\log\\");
    if(argc == 1)
    {
        //parseSyslogConfiguration();
        if (loggingLevel > 4)
            loggingLevel=DEBUG_LOG;

    }
    else
    {
        memset(a,0,sizeof(a));
        strncpy(a,argv[1],1);
        int isnum=isdigit(a[0]);
        printf("len argv : %d , isdigit : %d\n",strlen(argv[1]),isnum);
        //parseSyslogConfiguration();
        if(strlen(argv[1]) == 1 && isnum == 1)
        {

            loggingLevel = atoi(argv[1]);
            if (loggingLevel > 4)
                loggingLevel=DEBUG_LOG;

            printf("Current Log level initaited : %d",loggingLevel);
        }
        else
        {
            loggingLevel=DEBUG_LOG;
            printf("Invalid arg (%s)for syslog server setting log level to DEBUG\n",argv[1]);
            printf("Values can be from : 0-4 \n");
        }
    }

    if(buf[strlen(logBasePath)-1] != '\\')
    {
        printf("ADDING END SLASH\n");
        strncat(logBasePath,"\\",1);
    }
    else
        printf("NOT ADDING END SLASH\n");

    //g_thread_init(NULL);
    //write_mutex = g_mutex_new();
    slen = sizeof(si_other) ;
    getdatetime(&dateinfo);
    strcpy(logFileName,"syslog");
    memset(fileNameWithPath,0,sizeof(fileNameWithPath));
    strcat(fileNameWithPath,logBasePath);
    strcat(fileNameWithPath,logFileName);
    //strcat(fileNameWithPath,logFileName,logBasePath,"syslog");
    status = stat(fileNameWithPath, &sts);
    if(errno == ENOENT)
    {
        fp = fopen(fileNameWithPath, "a+");
        logMessage(fp,dateinfo.syslogTimeFormat,"LOGROTATE","[origin software='TEST']",0);
        fclose(fp);
    }
    getdatetime(&dateinfo);
    setSyslogFileDate(logBasePath);

    //Initialise winsock
    printf("\nInitialising Winsock...");
    if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
    {
        printf("Failed. Error Code : %d",WSAGetLastError());
        exit(EXIT_FAILURE);
    }
    printf("Initialised.\n");

    //Create a socket
    if((s = socket(AF_UNIX , SOCK_DGRAM , 0 )) == INVALID_SOCKET)
    {
        printf("Could not create socket : %d" , WSAGetLastError());
    }
    printf("Socket created.\n");

    //Prepare the sockaddr_in structure
    server.sin_family = AF_UNIX;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons( PORT );
    //Bind
    if( bind(s ,(struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR)
    {
        printf("Bind failed with error code : %d" , WSAGetLastError());
        exit(EXIT_FAILURE);
    }
    puts("Bind done");
    //msgQueueId = g_queue_new();
    //g_queue_init(msgQueueId);
  //  syslogFileWriteThreadId = g_thread_create(ProcessLogMsgfunc, NULL, TRUE, &error);
   // syslogRotateThreadId = g_thread_create(syslogRotateMonitor, NULL, TRUE, &error);
    //keep listening for data
    while(1)
    {
        fflush(stdout);
        memset(buf,'\0', BUFLEN);
        if ((recv_len = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen)) == SOCKET_ERROR)
        {
            printf("recvfrom() failed with error code : %d" , WSAGetLastError());
            exit(EXIT_FAILURE);
        }

        LOGSTRUCT *qMsg = NULL;
        memset(&message,0,sizeof(LOGSTRUCT));
        qMsg = malloc(sizeof(LOGSTRUCT));
        memset(qMsg,0,sizeof(LOGSTRUCT));
        memcpy(qMsg,&buf,sizeof(LOGSTRUCT));
        PostMessageQ(qMsg);

    }
//  g_mutex_free(write_mutex);
//  g_queue_free(msgQueueId);
    closesocket(s);
    WSACleanup();
//    g_thread_join(syslogFileWriteThreadId);
//    g_thread_join(syslogRotateThreadId);
    return 0;
}


客户端实现:

    #include<stdio.h>
    #include<winsock2.h>
    //#include <glib.h>

    #define DEBUG_LOG 0
    #define TRACE_LOG 1
    #define WARNING_LOG 2
    #define ERROR_LOG 3
    #define FATAL_LOG 4

    #pragma comment(lib,"ws2_32.lib") //Winsock Library

    #define SERVER "127.0.0.1"  //ip address of udp server
    #define BUFLEN 4096  //Max length of buffer
    #define PORT 514   //The port on which to listen for incoming data

    #define RUN_SERVER 1

    struct sockaddr_in si_other;
    int s;


    GMutex *write_mutex = NULL;

    static char appLogName[128] = {'0'};

    typedef enum{
        LOGINIT,
        LOGMESSAGE,
        LOGTRACE,
        LOGEXIT
    }logCommand;

    typedef struct
    {
        logCommand command;
        int logLevel;
        int pid;
        char appName[128];
        char loggerMessage[3200];
    }LOGSTRUCT, *LPLOGSTRUCT;



    int log_init(char *infoName,int level)
    {
        int ret=0;
        WSADATA wsa;
        //if(write_mutex == NULL)
        //{
            //g_thread_init(NULL);
            //write_mutex = g_mutex_new();
             //Initialise winsock
                if(strlen(infoName) == 0 && strlen(appLogName) == 0)
                {
                    strcpy(appLogName,"ATM");
                }
                else
                {
                    strcpy(appLogName,infoName);
                }


                //create socket
                if ( (s=socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == SOCKET_ERROR)
                {
                    printf("socket() failed with error code : %d" , WSAGetLastError());
                    //exit(EXIT_FAILURE);
                    return -1;
                }
                //int nOpt=1;
                //setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char*)&nOpt, sizeof(int));
                //setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&nOpt, sizeof(int));


                //setup address structure
                memset((char *) &si_other, 0, sizeof(si_other));
                si_other.sin_family = AF_INET;
                si_other.sin_port = htons(PORT);
                si_other.sin_addr.S_un.S_addr = INADDR_ANY;
                //si_other.sin_addr.S_un.S_addr = inet_addr(SERVER);
               // si_other.sin_addr.S_un.S_addr = INADDR_BROADCAST ;
               // si_other.sin_addr.s_addr = INADDR_ANY;


        //}
        return 0;
    }

    void log_exit()
    {
        RUN_SERVER=0;
        closesocket(s);
        WSACleanup();
    }

    void ms_log(char *buf,int priority)
    {
        debug_log(buf,priority);
    }

    void debug_log(char *buf,int priority)
    {
        //g_mutex_lock(write_mutex);
        int ret = 0;
        LOGSTRUCT log;
        memset(&log,0,sizeof(LOGSTRUCT));
        log.command=LOGMESSAGE;
        log.logLevel=priority;
        log.pid = GetCurrentProcessId();
        if(strlen(appLogName))
        {
            strcpy(log.appName,appLogName);
        }
        if(strlen(buf))
        {
            strcpy(log.loggerMessage,buf);
            ret=sendDataPacket(&log , sizeof(LOGSTRUCT));
        }
        //g_mutex_unlock(write_mutex);
    }

    int sendDataPacket(LOGSTRUCT *data , int dataLength)
    {
        BOOL bResult;
        DWORD cbBytes;
        int slen;
        slen=sizeof(si_other);
        if (sendto(s, data, dataLength , 0 , (struct sockaddr *) &si_other, slen) == SOCKET_ERROR)
        {
            printf("sendto() failed with error code : %d" , WSAGetLastError());
           return -1;
        }
        return 0;
    }

    int main(void)
    {
        char buf[BUFLEN];
        char message[BUFLEN];
        WSADATA wsa;
        LOGSTRUCT log;
        //start communication
        printf("\nInitialising Winsock...");
        if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
        {
            printf("Failed. Error Code : %d",WSAGetLastError());
            //exit(EXIT_FAILURE);
            return -2;
        }
        printf("Initialised.\n");
        log_init("TESTVEN",1);
        while(RUN_SERVER)
        {
            printf("Enter message : ");
            gets(message);
            log.command = LOGMESSAGE;
            strcpy(log.appName,"TESTAPP");
            log.logLevel=DEBUG_LOG;
            log.pid=GetCurrentProcessId();
            strcpy(log.loggerMessage,message);
            sendDataPacket(&log,sizeof(LOGSTRUCT));
            //send the message
        }
        log_exit();
        return 0;
    }

最佳答案

错误代码10049:WSAEADDRNOTAVAIL:无法分配请求的地址。


  请求的地址在其上下文中无效。这通常是由于尝试绑定到对于本地计算机无效的地址而导致的。当远程地址或端口对远程计算机无效(例如,地址或端口0)时,这也可能由connect,sendto,WSAConnect,WSAJoinLeaf或WSASendTo引起。


因此,sendto也可能发生。远程地址IP_ADDR_ANY不再是电缆插入上的有效地址吗?

如果它在同一台计算机上,还尝试在服务器代码上使用127.0.0.1吗?

关于c - Windows的自定义消息记录器的实现:拔出ntwk电缆时报告10049,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29861577/

10-15 02:09
查看更多