// jlidd-AutoOpenDoor.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include #include #include #include #include #include #include #pragma comment(lib,"ws2_32.lib") //使用UDP协议监听设备上报端口(默认为50000),处理设备上报数据。注意设备的“消息上报通信格式”需要配置为UDP,否则收不到数据。 void socketServer( int sock ) { printf("服务已经启动\n"); char msgBuf[1024] = {0}; struct sockaddr_in peeraddr ; socklen_t peerlen = sizeof(peeraddr) ; while(1) { memset ( msgBuf , 0 , sizeof(msgBuf)) ; int n = recvfrom ( sock , msgBuf , sizeof(msgBuf) , 0 , (struct sockaddr*) &peeraddr ,& peerlen ) ; if ( -1 == n ) { if ( EINTR == errno ) { continue ; } printf("接收数据失败\n") ; getchar(); exit(EXIT_FAILURE); } else if ( n>0 && n==strlen(msgBuf) ) //有内容并且是字符串,是刷卡实时上报 { sockaddr_in sin; memcpy(&sin, &peeraddr, sizeof(sin)); //打印出收到的数据。对于刷ic卡,可能打印出如下内容 //192.168.0.111:20675=>0578731147|1|10002|4|2018-01-17 17:22:35|1|1|1|北大门 //对应字段为 设备IP:设备端口=>卡号或条码|应用分类|控制器标志|控制器鉴权结果|控制器时间|读头号|门号|方向|设备名称 printf("%s:%05d=>%s\n",inet_ntoa(sin.sin_addr),sin.sin_port,msgBuf); //TODO.处理收到的数据,从内容中截取条码或者卡号,判断合法卡后发远程开门指令开门。 int checkOK = 0; std::string msg = msgBuf; std::string::size_type pos = msg.find("|"); std::string card; //卡号或者条码内容 if ( pos!=std::string::npos ) { card = msg.substr(0,pos); } //对于10位数字卡号,小于255表示特殊情况,不用处理 if ( card.size()==10 && atoi(card.c_str())<255 ) { continue; } //这里就不处理了,直接当成检查成功 checkOK = 1; if ( checkOK==1 ) { //开门3秒(用于普通门)=>具体开门指令格式参考开发文档。 //static char openDoorCmd[] = "\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x04\x00\x10\x00\x00\x03\x01\x01\x2c\x41"; //开门0.5秒(用于闸机)=>具体开门指令格式参考开发文档。 static char openDoorCmd[] = "\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x04\x00\x10\x00\x00\x03\x01\x00\x32\x46"; int n = sizeof(openDoorCmd); sendto ( sock , openDoorCmd , n , 0 , ( struct sockaddr*) &peeraddr , peerlen) ; } } else if ( (unsigned char)msgBuf[0]==0xc8 ) //0xc8开头的是其它上报消息,如连接检测消息,异步上报消息等。 { } else if ( (unsigned char)msgBuf[0]==0xaa ) //0xaa开头的是设备的返回指令,从这个范例来说,通常是上面开门指令的返回消息 { if ( msgBuf[0x1d]==1 ) { printf("=>远程开门返回成功\n"); } } } ::closesocket(sock) ; } int _tmain(int argc, char* argv[]) { WSADATA WSAData; int ret; if ((ret = WSAStartup(MAKEWORD(2,2), &WSAData)) != 0) { printf("初始化网络库失败\n"); return 1; } int sock = 0; if ( ( sock = socket ( PF_INET , SOCK_DGRAM , 0 ) ) < 0 ) { printf("创建句柄失败\n") ; getchar(); return 1; } struct sockaddr_in servaddr ; memset ( &servaddr , 0 , sizeof(servaddr) ) ; servaddr.sin_family = AF_INET ; if ( argc>1 ) { int port = atoi(argv[1]); servaddr.sin_port = htons(port) ; } else { servaddr.sin_port = htons(50000) ; } servaddr.sin_addr.s_addr = htonl(INADDR_ANY) ; if ( bind(sock,(struct sockaddr*) &servaddr , sizeof(servaddr) ) < 0 ) { printf("绑定端口失败\n") ; getchar(); return 1; } socketServer( sock ) ; WSACleanup(); return 0 ; }