您的位置:首页 > 大数据 > 人工智能

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

2016-09-23 16:29 585 查看

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);
}
//主循环体

bd03
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;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  VRPN