#include "stdafx.h" #include "NITools/NiNetwork.h" #include "buffer.h" #include "network.h" //#include "ParameterSet.h" /* 使用するパラメータ appParam.clientPort CSetNetwork appParam.animationUUID CSetAnimation appParam.printNetMode CSetLogMode appParam.printChkMode CSetLogMode */ CNiNetwork::CNiNetwork(void) { recvSocket = 0; sendSocket = 0; sharedMem = NULL; pLogDoc = NULL; appParam.init(); keepAliveTime = 3; // 3min memset(recvKey, 0, ANM_COM_LEN_IDKEY); memset(&serverDataAddr, 0, sizeof(struct sockaddr_in)); recvBuffer = make_Buffer(NINET_BUFFER_LEN); sendBuffer = make_Buffer(NINET_BUFFER_LEN); // Networkの初期化 see network.c init_network(); } CNiNetwork::~CNiNetwork(void) { DEBUG_ERR("DESTRUCTOR: CNiNetwork"); if (recvKey[0]!='\0') serverLogout(); closeRecvSocket(); closeSendSocket(); free_Buffer(&recvBuffer); free_Buffer(&sendBuffer); } char CNiNetwork::serverLogin(CString server, unsigned short sport, CString groupid) { int cc; struct sockaddr_in sv_addr; udp_header udphd; memset(&udphd, 0, sizeof(udp_header)); udphd.com[0] = ANM_COM_REQ_LOGIN; memcpy(udphd.key, (char*)(LPCSTR)groupid, ANM_COM_LEN_IDKEY); // int sock = udp_client_socket((char*)(LPCSTR)server, (int)sport, &sv_addr); cc = udp_send(sock, (char*)&udphd, sizeof(udp_header), &sv_addr); if (cc>0) cc = udp_recv(sock, (char*)&udphd, sizeof(udp_header), &sv_addr); if (cc<=0 || udphd.com[1]!=ANM_COM_REPLY_OK) { socket_close(sock); return udphd.com[1]; } // REGIST ::Sleep(NINET_REGIST_WAIT_TIME); // wait server sv_addr.sin_port = udphd.port; udphd.com[0] = ANM_COM_REQ_REGIST; udphd.port = htons((unsigned short)appParam.clientPort); memcpy(udphd.uuid, (char*)(LPCSTR)appParam.animationUUID, ANM_COM_LEN_UUID); cc = udp_send(sock, (char*)&udphd, sizeof(udp_header), &sv_addr); socket_close(sock); //if (cc>0) cc = udp_recv(sock, (char*)&udphd, sizeof(udp_header), &sv_addr); //if (cc<=0 || udphd.com[1]!=ANM_COM_REPLY_OK) return ANM_COM_REPLY_ERROR; memcpy(recvKey, udphd.key, ANM_COM_LEN_IDKEY); serverDataAddr = sv_addr; return ANM_COM_REPLY_OK; } void CNiNetwork::serverLogout(void) { udp_header udphd; memset(&udphd, 0, sizeof(udp_header)); udphd.port = htons((unsigned short)appParam.clientPort); memcpy(udphd.key, recvKey, ANM_COM_LEN_IDKEY); memcpy(udphd.uuid, (char*)(LPCSTR)appParam.animationUUID, ANM_COM_LEN_UUID); int sock = socket(AF_INET, SOCK_DGRAM, 0); // udphd.com[0] = ANM_COM_REQ_DELETE; udp_send(sock, (char*)&udphd, sizeof(udp_header), &serverDataAddr); // udphd.com[0] = ANM_COM_REQ_LOGOUT; udp_send(sock, (char*)&udphd, sizeof(udp_header), &serverDataAddr); socket_close(sock); if (sharedMem!=NULL) { sharedMem->clearNetworkAnimationIndex(); sharedMem->clearNetworkAnimationData(); } memset(&serverDataAddr, 0, sizeof(struct sockaddr_in)); memset(recvKey, 0, ANM_COM_LEN_IDKEY); } void CNiNetwork::openRecvSocket(void) { recvSocket = udp_server_socket((int)appParam.clientPort); return; } void CNiNetwork::openSendSocket(void) { sendSocket = socket(AF_INET, SOCK_DGRAM, 0); return; } void CNiNetwork::closeRecvSocket(void) { if (recvSocket>0) { socket_close(recvSocket); recvSocket = 0; } } void CNiNetwork::closeSendSocket(void) { if (sendSocket>0) { socket_close(sendSocket); sendSocket = 0; } } //////////////////////////////////////////////////////////////////////////////////////// // // スレッド // // // データ受信 // UINT niNetworkRecieveLoop(LPVOID pParam) { if (pParam==NULL) return 1; CNiNetwork* niNetwork = (CNiNetwork*)pParam; if (niNetwork->recvSocket<=0 || niNetwork->sharedMem==NULL) return 1; struct sockaddr_in ds_addr; time_t ntm, ptm = time(NULL); int num = 0; float frate = 0.0; unsigned short delay = 0; // while (niNetwork->recvSocket>0) { int cc = udp_recv_Buffer(niNetwork->recvSocket, &(niNetwork->recvBuffer), &ds_addr); if (cc>0) { char* ptr = (char*)niNetwork->recvBuffer.buf; udp_header* udphd = (udp_header*)ptr; int joints = (int)ntohs(udphd->num); int size = (int)ntohs(udphd->sz); if (!strncasecmp(udphd->key, niNetwork->recvKey, ANM_COM_LEN_IDKEY)) { if (udphd->com[0]==ANM_COM_REQ_DELETE) { ptr = NULL; } else { ptr += sizeof(udp_header); } // Log if (!isNull(niNetwork->pLogDoc)) { niNetwork->pLogDoc->lock(); if (niNetwork->appParam.printNetMode) { if (niNetwork->pLogDoc!=NULL) { niNetwork->pLogDoc->printFormat("NET: %s (%2d) [%d]\n", udphd->uuid, joints, size); } } if (niNetwork->appParam.printChkMode) { num++; ntm = time(NULL); if (ntm>ptm+NINET_FRM_RATE_INTVL-1 && !strncmp(niNetwork->appParam.animationUUID, udphd->uuid, ANM_COM_LEN_UUID)) { frate = (float)num/(float)(ntm - ptm); ptm = ntm; num = 0; unsigned short tm = ntohs(*(unsigned short*)&(udphd->com[2])); delay = GetMsecondsLapTimer(tm); int n = niNetwork->sharedMem->getNetworkAnimationIndexNum(); if (niNetwork->pLogDoc!=NULL) { niNetwork->pLogDoc->printFormat("NET: CHECK: %4.1f packets/s %4d ms (%2d) [%s]\n", frate, delay, n, udphd->key); } } } if (!isNull(niNetwork->pLogDoc)) niNetwork->pLogDoc->unlock(); } // niNetwork->sharedMem->updateNetworkAnimation(ptr, udphd->uuid, joints, size); } } } return 0; } // // Keep Alive // UINT niNetworkKeepAlive(LPVOID pParam) { if (pParam==NULL) return 1; CNiNetwork* niNetwork = (CNiNetwork*)pParam; udp_header udphd; memset(&udphd, 0, sizeof(udp_header)); udphd.com[0] = ANM_COM_REQ_ALIVE; udphd.port = htons((unsigned short)niNetwork->appParam.clientPort); memcpy(udphd.key, niNetwork->recvKey, ANM_COM_LEN_IDKEY); memcpy(udphd.uuid, (char*)(LPCSTR)niNetwork->appParam.animationUUID, ANM_COM_LEN_UUID); int sock = socket(AF_INET, SOCK_DGRAM, 0); int sleep_time = 60000*niNetwork->keepAliveTime; ::Sleep(sleep_time); // while (niNetwork->serverDataAddr.sin_port!=0) { udp_send(sock, (char*)&udphd, sizeof(udp_header), &niNetwork->serverDataAddr); ::Sleep(sleep_time); } socket_close(sock); return 0; }