VRPN-main源码分析(1/2).md

来源:互联网 发布:java读取zip文件夹 编辑:程序博客网 时间:2024/05/21 20:57

VRPN-main源码分析(1/2)

vrpn.c主函数main:

int main(int argc, char *argv[]){    const char *config_file_name = "vrpn.cfg";    bool bail_on_error = true;    bool auto_quit = false;    bool flush_continuously = false;    int realparams = 0;    int i;    int port = vrpn_DEFAULT_LISTEN_PORT_NO;#ifdef _WIN32    int milli_sleep_time = 0;#else    int milli_sleep_time = 1; #endif#ifdef _WIN32    WSADATA wsaData;    int status;    //windows下socket编程的启动命令,为了后续使用    //Windows Sockets API函数    if ((status = WSAStartup(MAKEWORD(1, 1), &wsaData)) != 0) {        fprintf(stderr, "WSAStartup failed with %d\n", status);        return (1);    }    //设置了多种信号处理函数,都是用来让vrpn 退出    //下面的while循环    SetConsoleCtrlHandler(handleConsoleSignalsWin, TRUE);#else#ifdef sgi    sigset(SIGINT, sighandler);    sigset(SIGKILL, sighandler);    sigset(SIGTERM, sighandler);    sigset(SIGPIPE, sighandler);#else    signal(SIGINT, sighandler);    signal(SIGKILL, sighandler);    signal(SIGTERM, sighandler);    signal(SIGPIPE, sighandler);#endif // not sgi#endif // not WIN32    //这里是解析命令行参数    i = 1;    while (i < argc) {        //"-f"参数用来指定配置文件如果没有指定,就会用默认的        //vrpn.cfg文件        if (!strcmp(argv[i], "-f")) {             if (++i > argc) {                Usage(argv[0]);            }            config_file_name = argv[i];        }        //下面每次主循环轮询时间,单位毫秒        else if (!strcmp(argv[i],                         "-millisleep")) {             if (++i > argc) {                Usage(argv[0]);            }            milli_sleep_time = atoi(argv[i]);        }        //错误标志        else if (!strcmp(argv[i], "-warn")) {             bail_on_error = false;        }        //调试信息标志位        else if (!strcmp(argv[i], "-v")) {             verbose = true;            vrpn_System_TextPrinter.set_min_level_to_print(vrpn_TEXT_NORMAL);        }        //最后一个连接断开时退出程序        else if (!strcmp(argv[i], "-q")) {            auto_quit = true;        }        //指定网络接口,未指定即使用默认的        else if (!strcmp(argv[i], "-NIC")) {            if (++i > argc) {                Usage(argv[0]);            }            if (verbose) {                fprintf(stderr, "Listening on network interface card %s.\n",                        argv[i]);            }            g_NICname = argv[i];        }        //vrpn server的输入端,默认标准输入1        else if (!strcmp(argv[i], "-li")) {            if (++i > argc) {                Usage(argv[0]);            }            if (verbose) {                fprintf(stderr, "Incoming logfile name %s.\n", argv[i]);            }            g_inLogName = argv[i];        }        //vrpn server的输出端,默认标准输出2        else if (!strcmp(argv[i], "-lo")) {            if (++i > argc) {                Usage(argv[0]);            }            if (verbose) {                fprintf(stderr, "Outgoing logfile name %s.\n", argv[i]);            }            g_outLogName = argv[i];        }        //log是否周期性得将缓冲中的数据刷新到硬盘内        else if (!strcmp(argv[i], "-flush")) {            flush_continuously = true;        }        else if (argv[i][0] == '-') { // Unknown flag            Usage(argv[0]);        }        else            switch (realparams) { // Non-flag parameters            case 0:                port = atoi(argv[i]);                realparams++;                break;            default:                Usage(argv[0]);            }        i++;    }    //根据启动server时候指定的-NIC参数,来创建vrpn_Connection,这个    //连接非常的重要,所有vrpn_Generic_Server_Object内的设备都要通过    //此连接上报数据,默认填充端口号为3883    std::stringstream con_name;    if (g_NICname) {        con_name << g_NICname;    }    con_name << ":" << port;    connection =        vrpn_create_server_connection(con_name.str().c_str(), g_inLogName, g_outLogName);    //用上面的连接来创建通用设备对象的服务端    //这里默认已经加载了非常多的设备驱动,比如之前上文用到的    //vrpn_Mouse,所以我们之前没有添加设备驱动就能够读取数据了    //此接口后面会专门分析代码    generic_server = new vrpn_Generic_Server_Object(        connection, config_file_name, verbose, bail_on_error);    if ((generic_server == NULL) || !generic_server->doing_okay()) {        fprintf(stderr, "Could not start generic server, exiting\n");        shutDown();    }    //创建代理服务,主要注册了2个回调函数    forwarderServer = new vrpn_Forwarder_Server(connection);    //如果参数指定了"-q",这里会处理1个回到函数,    //在最后一个连接关闭时,会自动退出程序    if (auto_quit) {        int dlc_m_id =            connection->register_message_type(vrpn_dropped_last_connection);        connection->register_handler(dlc_m_id, handle_dlc, NULL);    }    //主循环体    while (!done) {        //通用设备对象的mainloop函数,mainloop在vrpn中是很重要的虚函数        if (generic_server) {            generic_server->mainloop();        }        //处理连接上的数据收发        connection->mainloop();        //循环的将数据从缓冲区中刷新到硬盘上        if (flush_continuously) {            connection->save_log_so_far();        }        //连接异常时候直接直接退出        if (!connection->doing_okay()) {            shutDown();        }        //处理代理服务器上的任务        forwarderServer->mainloop();// 轮询间隔默认1ms一次#if defined(_WIN32)        if (milli_sleep_time >= 0) {#else        if (milli_sleep_time > 0) {#endif            vrpn_SleepMsecs(milli_sleep_time);        }    }    //退出程序    shutDown();    return 0;
0 0