⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 update_server.cpp

📁 一个简单的服务器升级更新程序
💻 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 + -