/******************QuerySocketReadble******************************* 函数功能:查询套接字是否可读,若可读,函数返回;否则直到超时,返回 本函数的主要功能是使socket读取变为非阻塞,可外部干预的。 参数: ver_len: 版本号数据长度(输出) pfile_buf 存储升级数据的缓冲区指针(输出) file_len: 升级数据长度(输出) fpReadIn: 文件指针(输入) 返回值: 1:升级文件读入成功 -1:文件版本读入错误 File_Crc32 error ****************************************************************/ int QuerySocketReadble( SOCKET sockSrv,int *ver_len, unsigned char*pfile_buf, unsigned long *file_len,FILE * fpReadIn) { fd_set fds; struct timeval timeout; timeout.tv_sec=0; timeout.tv_usec=0; while(1) { FD_ZERO(&fds); FD_SET(sockSrv,&fds); if(select(sockSrv+1,&fds,NULL,NULL,&timeout)>0) //判断SOCKET是否可读 if(FD_ISSET(sockSrv,&fds)>0) break; if(ReadFileAble==READFILE) { LogDisplay("更新升级文件...\r\n"); memset(Ver_Buf,0,*ver_len); //更新版本号前,清空缓冲区; if(ReadFileProcess( ver_len, pfile_buf, file_len,fpReadIn )<0) return -1; LogDisplay("等待STB连接!waiting...\r\n\r\n"); ReadFileAble=WAITACCEPT; } if(ReadFileAble==KILLTHREAD) { return -1; } } return 1; }
int ReadVersion(char *Ver_Buf,char*Version_File) { FILE * fpVersion=NULL; int read_len=0; int file_len=0; char *temp=Ver_Buf; if((fpVersion= fopen(Version_File,"rb")) == NULL) { LogDisplay("文件版本数据打开失败!\r\n"); return -1; } while(!feof(fpVersion)) { /*每次读BUFFER_SIZE个字节,并返回成功读取的字节数*/ if((read_len = fread(temp,sizeof(char),10,fpVersion))>0) { temp+=read_len; file_len+=read_len; } } memset(Print_Buf,0,sizeof(Print_Buf)); sprintf(Print_Buf,"update version: %s \r\n",Ver_Buf); LogDisplay(Print_Buf); return file_len; }
NS_IMETHODIMP nsProfileCollector::OnNewLog() { if (mLoggedProfile) { return NS_OK; } nsMetricsService *ms = nsMetricsService::get(); nsCOMPtr<nsIMetricsEventItem> profileItem; ms->CreateEventItem(NS_LITERAL_STRING("profile"), getter_AddRefs(profileItem)); NS_ENSURE_STATE(profileItem); LogCPU(profileItem); LogMemory(profileItem); LogOS(profileItem); LogInstall(profileItem); LogExtensions(profileItem); LogPlugins(profileItem); LogDisplay(profileItem); LogBookmarks(profileItem); nsresult rv = ms->LogEvent(profileItem); NS_ENSURE_SUCCESS(rv, rv); mLoggedProfile = PR_TRUE; return NS_OK; }
unsigned long File_Crc32( unsigned char*pfilebuf, unsigned long *filelen,FILE *fp,char*File_Name) { int file_block_length=0; unsigned long CRC32=0; unsigned char*temp=NULL; unsigned long file_length=0; /*参数容错*/ if(pfilebuf==NULL||File_Name==NULL||filelen==NULL) { LogDisplay("File_Crc32:parameter error!\r\n"); return -1; } temp=pfilebuf; *filelen=0; if((fp=fopen(File_Name,"rb")) == NULL) { LogDisplay("升级文件打开失败!\r\n"); return -1; } while(!feof(fp)) { /*每次读BUFFER_SIZE个字节,并返回成功读取的字节数*/ if((file_block_length = fread(temp,sizeof(char),BUF_SIZE,fp))>0) { temp+=file_block_length; file_length+=file_block_length; } } fclose(fp); sprintf(Print_Buf,"File:\t%s Read In Buffer Finished!\r\n",File_Name); LogDisplay(Print_Buf); sprintf(Print_Buf,"File Length is %d\r\n",file_length); LogDisplay(Print_Buf); LogDisplay("添加CRC校验\r\n"); CRC32=CRC_32(pfilebuf,file_length); *(pfilebuf+file_length)= (CRC32&0xff000000)>>24; *(pfilebuf+file_length+1)=(CRC32&0x00ff0000)>>16; *(pfilebuf+file_length+2)=(CRC32&0x0000ff00)>>8; *(pfilebuf+file_length+3)=(CRC32&0x000000ff); *filelen=file_length; return CRC32; }
/**************缓冲区文件发送*****************/ int FileBuf_Send(unsigned char* Filebuf, unsigned long filelen,SOCKET sockConn) { int send_length=0,send_num=0,len=0; unsigned char*temp=NULL; temp=Filebuf; while(1) { len=(filelen+4)-send_num; //剩余未发送数据长度 if(len>BUF_SIZE) { if((send_length=send(sockConn,(char*)temp,BUF_SIZE,0))<0) { sprintf(Print_Buf,"send error:%d\r\n", WSAGetLastError()); LogDisplay(Print_Buf); return -1; } temp+=send_length; send_num+=send_length; Send_Delay(); } else { if(len>(BUF_SIZE-4)) LogDisplay("尾部溢出!!!\r\n"); if((send_length=send(sockConn,(char*)temp,len,0))<0) { return -1; } temp+=send_length; send_num+=send_length; Send_Delay(); if((send_length=send(sockConn,"end",strlen("end")+1,0))<0) { return -1; } sprintf(Print_Buf,"send_num = %d\r\n",send_num); LogDisplay(Print_Buf); break; } } return 1; }
/******************Socket_Init*********************************** 函数功能:服务器端socket的建立与端口绑定 输入: 无 输出: sockSrv 建立成功后返回的套接字号 -1 winsock服务失败 套接字创建失败 端口绑定失败 ****************************************************************/ SOCKET Socket_Init(void) { WORD wVersionRequested; WSADATA wsaData; int err; SOCKADDR_IN addrSrv; wVersionRequested = MAKEWORD( 1, 1 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { return -1; } if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 ) { WSACleanup( ); return -1; } LogDisplay("创建服务器socket连接!\r\n"); SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP ); if(sockSrv<0) { LogDisplay("服务器socket连接创建失败!\r\n"); return -1; } addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY); //ip地址为10.30.100.250 addrSrv.sin_family=AF_INET; addrSrv.sin_port=htons(6000); if(bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR_IN))!=0) // 绑定端口 { sprintf(Print_Buf,"服务器端口绑定失败!%d\r\n", WSAGetLastError()); LogDisplay(Print_Buf); return -1; } int nNetTimeout=1000; //1秒 setsockopt(sockSrv,IPPROTO_TCP,SO_SNDTIMEO,(char *)&nNetTimeout,sizeof(int)); //yx设置发送超时时间 return sockSrv; }
int ReadFileProcess(int *ver_len, unsigned char*pfile_buf, unsigned long *file_len,FILE * fpReadIn ) { LogDisplay("读入文件版本\r\n"); if((*ver_len=ReadVersion(Ver_Buf,Version_File_Name))<0) return -1; #if 0 /*文件DES加密后输出*/ LogDisplay("对升级文件进行加密...\r\n"); if(DES_Encrypt(FileName,keyStr,DESFileName)<0) { sprintf(Print_Buf,"File:\t%s DES Encrypt Failed!\r\n",FileName); LogDisplay(Print_Buf); return -1; } sprintf(Print_Buf,"File: %s DES EncryptSucceed!\r\n",FileName); LogDisplay(Print_Buf); /*加密文件读入并加入CRC校验*/ LogDisplay("加密文件添加CRC校验...\r\n"); #endif LogDisplay("读入升级文件...\r\n"); memset(pfile_buf,0,FLIE_BUFFER_SIZE); /*文件读入并CRC32校验*/ if( File_Crc32( pfile_buf, file_len,fpReadIn,FileName)<0) { return -1; } return 1; }
/**********接收机顶盒消息,没有while循环只接受一次,30秒等待************/ int Receive_StbInfo(SOCKET sockConn) { char recvBuf[50]; int recv_len=0; fd_set fds; struct timeval time_out; time_out.tv_sec=30; time_out.tv_usec=0; FD_ZERO(&fds); FD_SET(sockConn,&fds); if(select(sockConn+1,&fds,NULL,NULL,&time_out)>0) //判断SOCKET是否可读 30秒阻塞时间 { if(FD_ISSET(sockConn,&fds)>0) { memset(recvBuf,0,50); recv_len=0; if((recv_len=recv(sockConn,recvBuf,50,0))<0) // 接受客户端消息 return -1; if(recv_len==sizeof(UpdateId)) { if(recvBuf[0]=='u'&&recvBuf[1]=='p'&&recvBuf[2]=='i'&&recvBuf[3]=='d') { sprintf(Print_Buf,"接收机顶盒信息:%s\r\n",recvBuf); LogDisplay(Print_Buf); return UPDATE_ID; } sprintf(Print_Buf,"receive data:%s\r\n",recvBuf); LogDisplay(Print_Buf); } if(recv_len==sizeof(CloseId)) { if(recvBuf[0]=='c'&&recvBuf[1]=='l'&&recvBuf[2]=='o'&&recvBuf[3]=='s'&&recvBuf[4]=='e') { sprintf(Print_Buf,"接收机顶盒信息:%s\r\n",recvBuf); LogDisplay(Print_Buf); return CLOSED_ID; } sprintf(Print_Buf,"receive data:%s\r\n",recvBuf); LogDisplay(Print_Buf); } if(recv_len==sizeof(ReSendId)) { if(recvBuf[0]=='r'&&recvBuf[1]=='e'&&recvBuf[2]=='s'&&recvBuf[3]=='e'&&recvBuf[4]=='n'&&recvBuf[5]=='d') { sprintf(Print_Buf,"接收机顶盒信息:%s\r\n",recvBuf); LogDisplay(Print_Buf); return RESEND_ID; } sprintf(Print_Buf,"receive data:%s\r\n",recvBuf); LogDisplay(Print_Buf); } } } return -1; // select错误或select超时或数据接收错误 }
int FileSend(unsigned char* pfile_buf, unsigned long file_len,SOCKET sockConn) { char ReSendNum=0; char RET=0; while(ReSendNum<3) { LogDisplay("发送升级数据...\r\n"); if(FileBuf_Send(pfile_buf,file_len,sockConn)<0) { sprintf(Print_Buf,"File_Send:\t%s Failed!\r\n", FileName); LogDisplay(Print_Buf); LogDisplay("close current connect!\r\n"); return -1; } sprintf(Print_Buf,"升级文件: %s 发送完毕!\r\n",FileName); LogDisplay(Print_Buf); LogDisplay("等待STB确认信息\r\n"); RET=0; RET=Receive_StbInfo(sockConn);//接受STB消息 if(RET==RESEND_ID) { LogDisplay("机顶盒端要求数据重传!\r\n"); ReSendNum++; continue; } if((ReSendNum>=2)&&(RET==CLOSED_ID)) { LogDisplay("重传3次数据校验有误!\r\n"); break; } break; } if(ReSendNum==3) { LogDisplay("重传3次数据发送失败!\r\n"); return -1; } return RET; }
void SeverSocket(void) { SOCKET sockSrv; //服务器套接字号 SOCKADDR_IN addrClient; //连接上的客户端ip地址 int len=sizeof(SOCKADDR); //SOCKADDR结构体大小 int flag=0; //存储接收到的STB消息类型 FILE * fpReadIn=NULL; // 文件指针 unsigned char sendbuffer[BUF_SIZE]; //发送缓冲区 unsigned char*pfile_buf=NULL; //存储文件的缓冲区指针 unsigned long file_len=0; //文件长度 int send_len=0; //发送的数据长度 int ver_len=0; //版本数据的长度(最大19个字节) ReadFileAble=READFILE; //文件标识置为“正在读入” pfile_buf = ( unsigned char *) malloc (FLIE_BUFFER_SIZE); if(pfile_buf==NULL) { LogDisplay("内存分配失败!\r\n"); return; } if(ReadFileProcess( &ver_len, pfile_buf, &file_len,fpReadIn )<0) return; sockSrv=Socket_Init(); //服务器sokcet连接初始化 LogDisplay("监听STB连接请求\r\n\r\n"); if(( listen(sockSrv,20))!=0) { sprintf(Print_Buf,"监听失败!%d\r\n", WSAGetLastError()); LogDisplay(Print_Buf); closesocket(sockSrv); free(pfile_buf); return ; } while(1) { LogDisplay("等待STB连接!waiting...\r\n"); memset(sendbuffer,0,sizeof(sendbuffer)); ReadFileAble=WAITACCEPT; //文件标识置为“等待连接” if(QuerySocketReadble( sockSrv,&ver_len,pfile_buf,&file_len,fpReadIn)<0) { free(pfile_buf); return; } SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);// 接受客户端连接,获取客户端的ip地址 if(sockConn==INVALID_SOCKET) { sprintf(Print_Buf,"accept无效连接!%d \r\n",WSAGetLastError()); LogDisplay(Print_Buf); continue; } ReadFileAble=CONNECTING; //发送数据期间无法读入文件 LogDisplay("收到STB连接请求!\r\n"); sprintf(Print_Buf,"发送升级流版本号:%s \r\n",Ver_Buf); LogDisplay(Print_Buf); Ver_Buf[ver_len]=ver_len+1; //在Ver_buf最后填写总的数据长度(包括最后一位) if((send_len=send(sockConn,(char*)Ver_Buf,ver_len+1,0))<0) { LogDisplay("版本号发送失败!\r\n"); closesocket(sockConn); //断开连接 closesocket(sockSrv); free(pfile_buf); return ; } Ver_Buf[ver_len]=0; //解决发送一次后版本号尾部乱码问题 LogDisplay("等待STB确认信息...\r\n"); flag=Receive_StbInfo(sockConn); if(flag==CLOSED_ID) { LogDisplay("机顶盒程序版本已经最新\r\n"); LogDisplay("释放连接\r\n\r\n"); closesocket(sockConn); continue; } if(flag<0) { LogDisplay("接受STB信息失败!\r\n"); LogDisplay("释放连接\r\n\r\n"); closesocket(sockConn); continue; } /***************发送文件,接受STB消息*****************/ flag=0; flag=FileSend(pfile_buf,file_len,sockConn); if(flag==RESEND_ID) { LogDisplay("释放连接\r\n\r\n"); closesocket(sockConn); } if(flag==CLOSED_ID) { LogDisplay("机顶盒端接收完毕\r\n"); LogDisplay("释放连接\r\n\r\n"); closesocket(sockConn); } if(flag<0) { LogDisplay("连接错误,释放连接\r\n\r\n"); closesocket(sockConn); } } }