📄 update_server.cpp
字号:
#include "./update_server.h"
//initialize
void CODEC_InitUpdateList(void) {
cout<<"++CODEC_InitUpdateList()"<<endl;
memset(&dev_update_record_list, 0, sizeof(dev_update_record_list));
}
void Codec_PrintUpdateList(void) {
cout<<"++Codec_PrintUpdateList()"<<endl;
int i;
cout<<" Num \t DevType \t DevID \t DevIP \t LastUpdateTime"<<endl;
for(i=0; i<MAX_DEV_NUM_UPDATE; i++) {
if( 0 == dev_update_record_list[i].DevType
|| -1 == dev_update_record_list[i].DevID
|| 0 == strlen(dev_update_record_list[i].DevIP) ) {
continue;
} else {
cout<<"\t"
<<i<<" \t "
<<dev_update_record_list[i].DevType<<" \t "
<<dev_update_record_list[i].DevID<<" \t "
<<dev_update_record_list[i].DevIP<<" \t "
<<dev_update_record_list[i].UpdateTime.wYear<<"/"
<<dev_update_record_list[i].UpdateTime.wMonth<<"/"
<<dev_update_record_list[i].UpdateTime.wDay<<" "
<<dev_update_record_list[i].UpdateTime.wHour<<":"
<<dev_update_record_list[i].UpdateTime.wMinute<<":"
<<dev_update_record_list[i].UpdateTime.wSecond
<<endl;
}
}
}
//find device by (DevType, DevID) or DevIP, if failure return -1
int CODEC_FindInUpdateList(unsigned int DevType, int DevID, char *DevIP) {
cout<<"++CODEC_FindInUpdateList()"<<endl;
int i;
int index;
index = -1;
if (0 == DevType || -1 == DevID) { //find device by IP
if (DevIP != NULL) {
for(i=0; i<MAX_DEV_NUM_UPDATE; i++) {
if(0 == strcmp(dev_update_record_list[i].DevIP, DevIP)) {
index = i;
break;
}
}
}
} else { //find device by DevType and DevID
for(i=0; i<MAX_DEV_NUM_UPDATE; i++) {
if (dev_update_record_list[i].DevType==DevType
&& dev_update_record_list[i].DevID==DevID ) {
index = i;
break;
}
}
}
return index;
}
//add device, if failure return -1
int CODEC_AddToUpdateList(unsigned int DevType, int DevID, char *DevIP) {
cout<<"++CODEC_AddToUpdateList()"<<endl;
int i;
int index;
index = -1;
for(i=0; i<MAX_DEV_NUM_UPDATE; i++) {
if ( 0 == dev_update_record_list[i].DevType
|| -1 == dev_update_record_list[i].DevID
|| 0 == strlen(dev_update_record_list[i].DevIP)) {
dev_update_record_list[i].DevType = DevType;
dev_update_record_list[i].DevID = DevID;
strcpy(dev_update_record_list[i].DevIP, DevIP);
index = i;
update_list_num++;
break;
}
}
return index;
}
//delete device, if failure return -1
int CODEC_DelFromUpdateList(unsigned int DevType, int DevID, char *DevIP) {
cout<<"++CODEC_DelFromUpdateList()"<<endl;
int index;
//find device
index = CODEC_FindInUpdateList(DevType, DevID, DevIP);
if (index != -1) {
memset(&dev_update_record_list[index], 0, sizeof(DevUpdateRecStruct));
update_list_num--;
}
return index;
}
//升级服务器,等待客户连接
//收到请求信号后,发送update文件,客户端接收文件并覆盖
int CODEC_UpdateServer(void) {
cout<<"++CODEC_UpdateServer() start"<<endl;
// variable
sockaddr_in local;
SOCKET lisnskt;
bool on = true;
fd_set rset,tempset;
unsigned int maxfd;
int nready;
SOCKET connskt;
SOCKET tempskt;
SOCKET client[MAX_DEV_NUM_UPDATE];
int client_num = 0;
int i;
int maxi;
sockaddr_in from;
int fromlen;
int bytesRecv=0;
int bytesSend;
DevUpdatePktStruct update_pkt;
int fh;
int bytesRead;
char rBuf[MAX_DATA_BUF_LEN_UPDATE];
int index = -1;
WSADATA wsaData;
//WSAStartup initializes the program for calling WinSock.
//The first parameter specifies the highest version of the
//WinSock specification, the program is allowed to use.
int wsaret=WSAStartup(MAKEWORD(2, 0),&wsaData);
//WSAStartup returns zero on success, If it fails we exit.
if(wsaret!=0) {
printf("WSAStartup error!\n");
return FAILURE;
}
//Now we populate the sockaddr_in structure
memset(&local,0,sizeof(sockaddr_in));
local.sin_family=AF_INET;
local.sin_addr.s_addr=INADDR_ANY;
local.sin_port=htons(Codec_Update_Server_Port);
//create a socket
lisnskt=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(lisnskt==INVALID_SOCKET) {
printf("create listen socket error!\n");
return FAILURE;
}
//bind socket with server address(IP and port)
if(bind(lisnskt,(sockaddr*)&local,sizeof(local))!=0) {
printf("bind listen socket error!");
closesocket(lisnskt);
return FAILURE;
}
setsockopt(lisnskt, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
//listen socket if there is any connection request,
//we can accept MAX_CONNECT_NUM connections coinstantaneous
if(listen(lisnskt,MAX_DEV_NUM_UPDATE)!=0) {
printf("Error listening on socket.\n");
closesocket(lisnskt);
return FAILURE;
}
cout<<"Waiting for client to connect..."<<endl;
maxfd = lisnskt; //initialize
maxi = -1; //index to client[] array
for(i=0; i<MAX_DEV_NUM_UPDATE; i++) { //-1 indicates available entry
client[i] = 0;
}
FD_ZERO(&rset);
FD_SET(lisnskt,&rset);
while(!Update_Server_Off) {
tempset=rset;
nready=select(maxfd+1,&tempset,NULL,NULL,NULL);
if(nready == SOCKET_ERROR) {
cout<<"server select error, quiting..."<<endl;
continue;
}
//new client connection
if(FD_ISSET(lisnskt,&tempset)) {
fromlen=sizeof(from);
connskt=accept(lisnskt, (struct sockaddr*)&from, &fromlen);
cout<<"\nnew client: connection from "<<inet_ntoa(from.sin_addr)<<endl;
client_num++;
if(client_num > MAX_DEV_NUM_UPDATE) {
cout<<"too many client, ignore this client!"<<endl;
closesocket(connskt);
client_num = MAX_DEV_NUM_UPDATE;
} else {
// save descriptor
for(i=0; i<MAX_DEV_NUM_UPDATE; i++) {
if(client[i] <= 0) {
client[i]=connskt;
break;
}
}
FD_SET(connskt, &rset); //add new descriptor to set
if(connskt > maxfd) maxfd = connskt;
if(i > maxi) maxi = i;
}
if (--nready <= 0) continue;
}
for(i=0; i<=maxi; i++) {
if ( (tempskt=client[i]) <= 0 ) continue;
if(FD_ISSET(tempskt, &tempset) ) {
bytesRecv=recv(tempskt, (char *)&update_pkt, sizeof(DevUpdatePktStruct), 0);
if(bytesRecv == 0 || bytesRecv == SOCKET_ERROR) { //connection error
cout<<"client off line detected."<<endl;
closesocket(tempskt);
FD_CLR(tempskt, &rset);
client[i] = 0;
client_num--;
} else {
//parse the packet
//if "Request_Update", do update process
if ( 0 == strcmp(update_pkt.CmdHint, "Request_Update") ) {
cout<<"Request_Update recved..."<<endl;
//send File_Name
cout<<"File_Name send..."<<endl;
memset(update_pkt.CmdHint, 0, sizeof(update_pkt.CmdHint));
strcpy(update_pkt.CmdHint, "File_Name");
memset(update_pkt.DataBuf, 0, sizeof(update_pkt.DataBuf));
strcpy(update_pkt.DataBuf, UpDate_File_Name);
bytesSend = send(tempskt, (char *)&update_pkt, sizeof(DevUpdatePktStruct), 0);
if(bytesSend == SOCKET_ERROR ) {
cout<<"send error"<<endl;
closesocket(tempskt);
FD_CLR(tempskt, &rset);
client[i] = 0;
client_num--;
continue;
//goto nready_judge;
}
//send File_Begin, notify client to prepare for recv file content
cout<<"File_Begin send..."<<endl;
memset(update_pkt.CmdHint, 0, sizeof(update_pkt.CmdHint));
strcpy(update_pkt.CmdHint, "File_Begin");
memset(update_pkt.DataBuf, 0, sizeof(update_pkt.DataBuf));
strcpy(update_pkt.DataBuf, UpDate_File_Name);
bytesSend = send(tempskt, (char *)&update_pkt, sizeof(DevUpdatePktStruct), 0);
if(bytesSend == SOCKET_ERROR ) {
cout<<"send error"<<endl;
closesocket(tempskt);
FD_CLR(tempskt, &rset);
client[i] = 0;
client_num--;
continue;
//goto nready_judge;
}
//open update file
//.txt use option _O_TEXT, .mpg/.rar use option _O_BINARY
cout<<"open update file."<<endl;
fh = _open( UpDate_File_Name, _O_RDONLY );
if( fh == -1 ) {
cout<<"open failed on input file"<<endl;
return FAILURE;
}
//read file until file end
cout<<"File_Content send..."<<endl;
memset(update_pkt.CmdHint, 0, sizeof(update_pkt.CmdHint));
strcpy(update_pkt.CmdHint, "File_Content");
memset(rBuf, 0, sizeof(rBuf));
memset(update_pkt.DataBuf, 0, sizeof(update_pkt.DataBuf));
while ( (bytesRead = _read( fh, rBuf, sizeof(rBuf))) > 0 ) {
memcpy( update_pkt.DataBuf, rBuf, bytesRead );
bytesSend = send(tempskt, (char *)&update_pkt, sizeof(DevUpdatePktStruct), 0);
//cout<<"File_Content: bytesSend "<<bytesSend<<endl;
//Sleep(10);
if(bytesSend == SOCKET_ERROR ) {
cout<<"send error"<<endl;
closesocket(tempskt);
FD_CLR(tempskt, &rset);
client[i] = 0;
client_num--;
break;
//goto nready_judge;
}
memset(rBuf, 0, sizeof(rBuf));
memset(update_pkt.DataBuf, 0, sizeof(update_pkt.DataBuf));
}
//file end, close file
cout<<"close update file"<<endl;
_close( fh );
//send File_End, notify cilent to do update process
cout<<"File_End send..."<<endl;
memset(update_pkt.CmdHint, 0, sizeof(update_pkt.CmdHint));
strcpy(update_pkt.CmdHint, "File_End");
memset(update_pkt.DataBuf, 0, sizeof(update_pkt.DataBuf));
strcpy(update_pkt.DataBuf, UpDate_File_Name);
bytesSend = send(tempskt, (char *)&update_pkt, sizeof(DevUpdatePktStruct), 0);
if(bytesSend == SOCKET_ERROR ) {
cout<<"send error!"<<endl;
closesocket(tempskt);
FD_CLR(tempskt, &rset);
client[i] = 0;
client_num--;
continue;
//goto nready_judge;
}
} else if ( 0 == strcmp(update_pkt.CmdHint, "Update_Success") ) {
cout<<"Update_Success recved. modify update list..."<<endl;
//update success, record this operate
//find if the client exist in dev_update_record_list, return index
index = CODEC_FindInUpdateList( update_pkt.DevType, update_pkt.DevID,
update_pkt.DevIP );
//if not exist, add it
if ( -1 == index ) {
index = CODEC_AddToUpdateList( update_pkt.DevType, update_pkt.DevID,
update_pkt.DevIP );
}
//set the UpdateTime to current time
//GetSystemTime(&dev_update_record_list[index].UpdateTime);
GetLocalTime(&dev_update_record_list[index].UpdateTime);
Codec_PrintUpdateList();
} else if ( 0 == strcmp(update_pkt.CmdHint, "Update_Failure") ) {
cout<<"Update_Failure recved."<<endl;
} else {
//do nothing
cout<<"unexpected packet recerved, ignore it!"<<endl;
}
}
//nready_judge:
if(--nready<=0) //no more readable descriptors
break;
}
}
}
//When it has finished using the services of the WS2_32.DLL,
//the application or DLL must call WSACleanup to allow the
//WS2_32.DLL to free any resources for the application
WSACleanup();
return 0;
}
int main(void) {
int retval;
CODEC_InitUpdateList();
retval = CODEC_UpdateServer();
while(_getch()!=27);
return SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -