需要用到native程序上網接收文件到本地,需要的協議為http。
由於android本身自帶的chrome太過復雜,調用起來也不方便。在網上搜索過后,移植了libhttp到本地。比較簡單易用,但程序是否能很好的支持多線程,這個還需要繼續了解。
一開始參考網上的代碼寫了一個,但總是發現文件有錯亂。在仔細debug后,發現問題出在使用同步和異步獲取文件的問題上。在開發前,並沒有好好的去區分異步和同步,導致挖了個不小的坑。
一般在do{//寫文件}while(1)中,一般選擇使用同步的方式;
如果是set(callback)的方式,這時可以使用異步的方式。如果是異步的方式,一般涉及到對接收包的排序問題。異步的話,服務器壓力最小。
下面是錯誤的調用方式,設置了異步方式,同時使用do while(1)結構。只要修改下代碼中的協議方式即可。
樓主
發表於: 2012-06-09 11:24:23
我在使用libhttp 異步的請求一個10MB的數據,結果發現下載過來的文件會錯亂,具體信息:(1)下載過來的文件大小是對的。還是10MB;(2)但是文件在中間某些地方會錯亂。(3)代碼如下:
int _tmain(int argc, _TCHAR* argv[]) { WORD wVersionRequested=MAKEWORD(1,1); WSADATA wsaData; if(WSAStartup(wVersionRequested,&wsaData)) { return -1; } char *uri = "http://127.0.0.1:81/123.flv"; FILE *txt = fopen("D:\\m123.flv","wb"); char *buf; ///異步請求 int bytes = 0; int recvbytes = 0; ghttp_request *request; ghttp_status req_status; request = ghttp_request_new(); ///分配一個新的request if (ghttp_set_uri(request,uri) < 0) bail("ghttp_set_uri"); if(ghttp_set_type(request, ghttp_type_get) < 0) bail("ghttp_set_type"); if (ghttp_set_sync(request, ghttp_async) < 0)///設置異步請求 bail("ghttp_set_sync"); if (ghttp_prepare(request) < 0) bail("ghttp_prepare"); do { status(request, "conn0"); req_status = ghttp_process(request); if (req_status == ghttp_error) { fprintf(stderr, "ghttp err: %s\n", ghttp_get_error(request)); return 2; } if (req_status != ghttp_error && ghttp_get_body_len(request) > 0) { buf = ghttp_get_body(request); bytes = ghttp_get_body_len(request); recvbytes += bytes; fwrite(buf,bytes,1,txt); ghttp_flush_response_buffer(request); } } while (req_status == ghttp_not_done); ///實驗結果是接收數據大小完整,但是中間數據有錯亂, ///懷疑是ghttp_flush_response_buffer(request);造成? fprintf(stderr, "conn0 received %d bytes\n", recvbytes); ghttp_clean(request); ghttp_request_destroy(request); fclose(txt); getch(); return 0; } 請大家幫忙分析一下原因,謝謝! |