C++实现软件自动更新功能
0.用到的頭文件
| 1 2 | #include?<Shlwapi.h> #pragma?comment(lib,?"WS2_32")??//?鏈接到WS2_32.lib |
1.啟動Windows Sockets,初始化WS2_32.dll?
| 1 2 3 4 5 6 7 | ????WSADATA?wsaData; ????WORD?sockVersion?=?MAKEWORD(2,?2); ????if?(::WSAStartup(sockVersion,?&wsaData)?!=?0) ????{ ????????::WSACleanup(); ????????return?FALSE; ????} |
2. 通過"套接字"向網絡發出請求或者應答網絡請求.
| 1 2 3 4 5 6 7 | ????SOCKET?sClient; ????int?ret; ????sClient?=?socket(AF_INET,?SOCK_STREAM,?IPPROTO_TCP); ????if?(sClient?==?INVALID_SOCKET) ????{ ????????return?FALSE; ????} |
3.設置發送和接收時間為超時8秒
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | ????//?set?Recv?and?Send?time?out ????int?TimeOut?=?8000;?//?設置發送超時8秒 ????if?(setsockopt(sClient,?SOL_SOCKET,?SO_SNDTIMEO,?(char?*)&TimeOut,?sizeof(TimeOut))?==?SOCKET_ERROR) ????{ ????????closesocket(sClient); ????????return?FALSE; ????} ????if?(setsockopt(sClient,?SOL_SOCKET,?SO_RCVTIMEO,?(char?*)&TimeOut,?sizeof(TimeOut))?==?SOCKET_ERROR) ????{ ????????closesocket(sClient); ????????return?FALSE; ????} |
4.獲取與套接口相關的操作參數
| 1 2 3 4 5 6 7 | ????unsigned?long?ul?=?1; ????ret?=?ioctlsocket(sClient,?FIONBIO,?(unsigned?long?*)&ul); ????if?(ret?==?SOCKET_ERROR) ????{ ????????closesocket(sClient); ????????return?FALSE; ????} |
5.sockaddr結構初始化,可通過設置服務器ip或網站地址。
gethostbyname()返回對應于給定主機名的包含主機名字和地址信息的hostent結構指針。結構的聲明與gethostaddr()中一致。
inet_addr(const char* strptr)返回:若字符串有效則將字符串轉換為32位二進制網絡字節序的IPV4地址,否則為INADDR_NONE
| 1 2 3 4 5 6 7 8 9 10 11 12 | ????struct?sockaddr_in?server; ????server.sin_family?=?AF_INET; ????server.sin_port?=?htons(80); ????struct?hostent?*pURL?=?gethostbyname("www.yanxin8.com"); ????//const?char*?ip?=?"115.28.9.132"; ????//server.sin_addr.s_addr?=?inet_addr(ip); ????server.sin_addr.s_addr?=??*((unsigned?long*)pURL->h_addr); ????if?(server.sin_addr.s_addr?==?INADDR_NONE) ????{ ????????closesocket(sClient); ????????return?FALSE; ????} |
6.與遠程主機("www.yanxin8.com")建立連接
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ??BOOL?bConnRe?=?FALSE; ????if?(connect(sClient,?(struct?sockaddr?*)&server,?sizeof(server))?==?-1) ????{ ????????struct?timeval?timeout_val; ????????fd_set?set; ????????FD_ZERO(&set); ????????FD_SET(sClient,?&set); ????????timeout_val.tv_sec?=?1; ????????timeout_val.tv_usec?=?0; ????????if?(select(0,?NULL,?&set,?NULL,?&timeout_val)?>?0) ????????{ ????????????bConnRe?=?TRUE; ????????} ????????else ????????????bConnRe?=?FALSE; ????} ????else ????????bConnRe?=?TRUE; ????if?(!bConnRe) ????{ ????????closesocket(sClient); ????????return?FALSE; ????} |
7.等待接收時間協議返回的時間。學習了Winsock I/O模型之后,最好使用異步I/O,以便設置超時。??
? 按照http協議,發送請求數據
? char *request = "GET /version.txt HTTP/1.0\r\nHost:www.yanxin8.com\r\nConnection: Close\r\n\r\n";
? GET這個是表示以什么方式請求,HTTP中還有很多其他的請求方式,常用的GET? POST
? version.txt,要獲取的資源的名稱,version.txt為網站服務器根目錄下的文件
? HTTP/1.0表示http協議的版本
? Host:www.yanxin8.com,用來指定訪問的主機。
| 1 2 3 4 5 | ???int?nRecv?=?0; ????///version.txt ????char?*request?=?"GET?/version.txt?HTTP/1.0\r\nHost:www.yanxin8.com\r\nConnection:?Close\r\n\r\n"; ????ret?=?send(sClient,?request,?strlen(request),?0); ????Sleep(300); |
8.接收返回的數據,然后做解析。下面是返回的數據,可以看到最后一行為設定的軟件版本。
| 1 2 3 4 5 6 7 8 9 10 | HTTP/1.1?200?OK Date:?Wed,?29?Apr?2015?08:08:02?GMT Server:?Apache/2.4.10?(Unix)?OpenSSL/1.0.1e-fips?mod_fastcgi/2.4.6 Last-Modified:?Tue,?28?Apr?2015?11:04:41?GMT ETag:?"10-514c6d4462440" Accept-Ranges:?bytes Content-Length:?16 Connection:?close Content-Type:?text/plain noteCard=V1.0.2; |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 | ??char?buf[2000]?=?{?0?}; ????nRecv?=?::recv(sClient,?buf,?2000,?0); ????if?(nRecv?>?0){ ????????string?str(buf); ????????//strstr(buf,?"noteCard="); ????????int?pos1?=?str.find("noteCard="); ????????if?(pos1?!=?-1){ ????????????pos1?+=?9; ????????????int?pos2?=?str.find(";",?pos1); ????????????verstr?=?str.substr(pos1,?pos2?-?pos1); ????????????return?true; ????????} ????} |
9.關閉socket
| 1 2 3 | ????closesocket(sClient); ????::WSACleanup(); ?????return?FALSE; |
10.實現效果展示
總結
以上是生活随笔為你收集整理的C++实现软件自动更新功能的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: link st 量产工具_ST-Link
- 下一篇: MFC中GetDlgItemInt()方