C++中用Socket實現對結構體長字符串和圖片的傳輸_第1頁
C++中用Socket實現對結構體長字符串和圖片的傳輸_第2頁
C++中用Socket實現對結構體長字符串和圖片的傳輸_第3頁
C++中用Socket實現對結構體長字符串和圖片的傳輸_第4頁
C++中用Socket實現對結構體長字符串和圖片的傳輸_第5頁
已閱讀5頁,還剩6頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、C+中用Socket實現對結構體、長字符串和圖片的傳輸 首先說明下,本文的Socket傳輸引用了CBlockingSocket封裝類這個類比較特殊的是Send和Receive的最后一個參數是超時時間,其它與C庫里的類似首先說結構體吧,這里傳輸的結構體含有八個整型,如下cpp view plaincopyprint?1. typedefstructexceptiontypecount2. intimg_num;3. intptz_num;4. intpreset_num;5. intvideo_num;6. intdevice_num;7. inttotal_num;8. inttotal_ch

2、annel;9. intuseless;10. ExceptionCount,*pExceptionCount;typedef struct exceptiontypecount int img_num; int ptz_num; int preset_num; int video_num; int device_num; int total_num; int total_channel; int useless; ExceptionCount,*pExceptionCount;關于Socket的創(chuàng)建和連接這里就不說了,參見點擊打開鏈接這里只說下收發(fā)部分的實現服務端:cpp view plai

3、ncopyprint?1. cpp view plaincopyprint?1. memset(counttemp,0,256);/清空緩存2. memcpy(counttemp,&ExCount,sizeof(ExCount);/將結構體轉為字符串3. intcountlen=sockCon.Send(counttemp,256,1000); memset(counttemp,0,256);/清空緩存 memcpy(counttemp,&ExCount,sizeof(ExCount);/將結構體轉為字符串 int countlen = sockCon.Send(counttemp,256,1

4、000);其中,char countemp256, ExCount是實例化的結構體??蛻舳耍篶pp view plaincopyprint?1. memset(countbuff,0,256);2. intlen=sClient.Receive(countbuff,256,1000);/接受故障數據3. memset(&count,0,sizeof(count);4. memcpy(&count,countbuff,sizeof(count); memset(countbuff,0,256); int len = sClient.Receive(countbuff,256,1000); / 接

5、受故障數據memset( &count,0,sizeof(count);memcpy( &count, countbuff, sizeof(count) ); 這里的count即為輸出的結構體,countbuff同樣也是個char256。memset這一步非常重要,如果沒有預先清空緩存,就容易出現亂碼。=字符串:要傳一個500K左右的string字符串,肯定不能直接傳,因為Socket傳輸是有字節(jié)上限的,好像是16000+字節(jié)所以我們采用分段傳輸的策略服務端:cpp view plaincopyprint?1. sockCon.Send(allSize,allNum.GetLength(),1

6、00);2. if(!(sockCon.Receive(resbuff,2,10)3. 4. printf(數據量信息發(fā)送失敗n);5. return;6. 7. else8. printf(數據量信息發(fā)送成功n);9. 10. 11. temp=AllExDataPtr;12. BytesSent=0;13. while(BytesSentAllExDataSize)/分段傳輸數據14. 15. intBytesSentThisTime=sockCon.Send(temp,(AllExDataSize-BytesSent)256)?(AllExDataSize-BytesSent):256,

7、1000);16. BytesSent=BytesSent+BytesSentThisTime;17. temp=temp+BytesSentThisTime;18. sockCon.Send(allSize,allNum.GetLength(),100);if(!(sockCon.Receive(resbuff,2,10) printf(數據量信息發(fā)送失敗n); return ;else printf(數據量信息發(fā)送成功n); temp = AllExDataPtr; BytesSent = 0; while(BytesSentAllExDataSize)/分段傳輸數據 int BytesS

8、entThisTime=sockCon.Send(temp,(AllExDataSize-BytesSent)256)?(AllExDataSize-BytesSent):256,1000); BytesSent = BytesSent + BytesSentThisTime; temp = temp + BytesSentThisTime; 其中,AllExDataPtr是指向需要傳輸的string的一個char*指針,定義為:AllExDataPtr = (char*) AllExData.c_str(); AllSize就是這段數據的字節(jié)數,需要首先傳到客戶端,客戶端才可以正常接收客戶端

9、:cpp view plaincopyprint?1. intsizelen=sClient.Receive(sizebuff,10,50);/接受數據大小2. if(sizelen!=0)3. 4. charflag=1;5. sClient.Send(flag,2,10);6. 7. sizebuffsizelen=0;8. exsize=atoi(sizebuff);9. printf(數據大?。?dn,exsize);10. extemp=newcharexsize+256;/初始化存儲信息的數據,留出冗余空間,以防溢出11. exdata=extemp;/新建指針指向起始地址,方便接

10、收后調用12. 13. intBytesReceivedThisTime=0;14. while(BytesReceivedexsize)15. 16. BytesReceivedThisTime=sClient.Receive(temp,256,1000);17. strcpy(extemp,temp);18. BytesReceived=BytesReceived+BytesReceivedThisTime;19. extemp=extemp+BytesReceivedThisTime;20. 21. std:stringout=exdata;int sizelen = sClient.R

11、eceive(sizebuff,10,50);/接受數據大小if(sizelen !=0)char flag=1;sClient.Send(flag,2,10);sizebuffsizelen=0;exsize = atoi(sizebuff);printf(數據大?。?dn,exsize);extemp = new charexsize+256;/初始化存儲信息的數據,留出冗余空間,以防溢出exdata = extemp;/新建指針指向起始地址,方便接收后調用int BytesReceivedThisTime = 0;while(BytesReceived exsize)BytesRecei

12、vedThisTime = sClient.Receive(temp,256,1000);strcpy(extemp,temp);BytesReceived = BytesReceived + BytesReceivedThisTime;extemp = extemp + BytesReceivedThisTime; std:string out = exdata;其中out即為要輸出的string,這里建了兩個指針指向新建的char數組,其中extemp用于接收時的迭代,exdata用于調用該數組=圖片:要實現的就是收發(fā)圖片,這里只寫客戶端發(fā)服務端收的例子,其他均類似客戶端:cpp view

13、 plaincopyprint?1. intImageSocketClient:UploadFileBySocket(std:stringfilename,inttype)2. 3. CFileFindFinder;/確保本地有該文件4. if(!Finder.FindFile(filename.c_str()5. 6. return-1;/文件未找到7. 8. 9. charinbuff2;10. sockType=SOCKET_UPLOAD;/上傳操作標志位11. CStringstr;/將整形標志位轉成字符型12. str.Format(%d,sockType);13. char*fla

14、g=str.GetBuffer(0);14. 15. if(!m_bConnectOK)/如果Socket沒有連接16. 17. try18. 19. CSockAddrsaClient(m_strSocketAddress,5858);/設IP和端口20. m_SocketClient.Create();21. /創(chuàng)建套接字22. m_SocketClient.Connect(saClient);23. /發(fā)起連接24. m_SocketClient.Send(flag,str.GetLength(),4);/發(fā)送上傳標識符25. intlen=m_SocketClient.Receive(

15、inbuff,2,4);26. if(len=0)27. return0;28. else29. m_bConnectOK=TRUE;/連接成功30. 31. 32. catch(CBlockingSocketException*e)33. 34. delete(e);35. return0;36. 37. 38. else39. 40. try41. 42. m_SocketClient.Send(flag,str.GetLength(),4);/發(fā)送上傳標識符43. intlen=m_SocketClient.Receive(inbuff,2,4);44. if(len=0)45. ret

16、urn0;46. 47. catch(CBlockingSocketException*e)48. 49. delete(e);50. return0;51. 52. 53. 54. /獲取本地路徑55. charszPathMAX_PATH;56. GetCurrentDirectory(MAX_PATH,szPath);57. CStringstrpath(szPath);58. intidx=strpath.ReverseFind(_T();59. if(idx!=strpath.GetLength()-1)/如果最后一個字符不是(非根目錄),則添加。60. 61. strpath=st

17、rpath+;62. 63. /設置本地路徑+文件名64. CStringstrLocalFile;65. strLocalFile.Format(%s%s,strpath,filename.c_str();66. 67. CStringstrRemoteFile;68. /服務器保存路徑69. switch(type)70. 71. case1:72. strRemoteFile.Format(Preset%s,filename.c_str();73. break;74. case2:75. strRemoteFile.Format(IMG_Exception%s,filename.c_st

18、r();76. break;77. case3:78. strRemoteFile.Format(PTZ_Exception%s,filename.c_str();79. break;80. case4:81. strRemoteFile.Format(PRESET_Exception%s,filename.c_str();82. break;83. default:84. strRemoteFile=filename.c_str();85. break;86. 87. 88. /發(fā)送服務器保存路徑,方便后續(xù)存儲89. try90. 91. charinbuff2;92. char*buf=s

19、trRemoteFile.GetBuffer(0);93. m_SocketClient.Send(buf,MAX_PATH,5);94. intlen=m_SocketClient.Receive(inbuff,2,5);95. if(len=0)96. return0;/發(fā)送失敗97. 98. catch(CBlockingSocketException*e)99. 100. delete(e);101. return0;102. 103. 104. 105. 106. FILE*fstream=fopen(strLocalFile,rb);/讀取文件數據107. 108. if(NULL

20、=fstream)109. 110. printf(打開文件失敗,錯誤碼:%d,GetLastError();111. return0;112. 113. 114. intnNumRead=0;115. chartemp256;116. 117. if(NULL!=fstream)118. 119. WaitForSingleObject(m_hMutex,MutexTime_ImageSocket);120. printf(開始上傳n);121. while(!feof(fstream)/未到文件末尾,則繼續(xù)發(fā)送122. 123. nNumRead=fread(temp,1,256,fstr

21、eam);124. m_SocketClient.Send(temp,nNumRead,500);125. 126. printf(上傳成功n);127. fclose(fstream);128. ReleaseMutex(m_hMutex);129. 130. m_SocketClient.Close();131. m_SocketClient.Cleanup();132. return1;133. int ImageSocketClient:UploadFileBySocket(std:string filename, int type)CFileFind Finder;/確保本地有該文件

22、if (!Finder.FindFile(filename.c_str()return -1;/文件未找到char inbuff2;sockType = SOCKET_UPLOAD; /上傳操作標志位CString str; /將整形標志位轉成字符型str.Format(%d, sockType);char* flag = str.GetBuffer(0);if(!m_bConnectOK) /如果Socket沒有連接 tryCSockAddr saClient(m_strSocketAddress,5858);/設IP和端口m_SocketClient.Create();/創(chuàng)建套接字m_So

23、cketClient.Connect(saClient);/發(fā)起連接m_SocketClient.Send(flag,str.GetLength(),4); / 發(fā)送上傳標識符int len=m_SocketClient.Receive(inbuff,2,4);if(len = 0)return 0;elsem_bConnectOK = TRUE; /連接成功catch (CBlockingSocketException* e)delete(e);return 0;elsetrym_SocketClient.Send(flag,str.GetLength(),4); / 發(fā)送上傳標識符int

24、len=m_SocketClient.Receive(inbuff,2,4);if(len = 0)return 0;catch (CBlockingSocketException* e)delete(e);return 0;/ 獲取本地路徑char szPathMAX_PATH;GetCurrentDirectory(MAX_PATH, szPath);CString strpath(szPath);int idx = strpath.ReverseFind(_T();if( idx != strpath.GetLength()-1)/如果最后一個字符不是(非根目錄),則添加。strpath

25、 = strpath+;/設置本地路徑+文件名CString strLocalFile;strLocalFile.Format(%s%s,strpath,filename.c_str(); CString strRemoteFile;/服務器保存路徑switch (type)case 1:strRemoteFile.Format(Preset%s,filename.c_str();break;case 2:strRemoteFile.Format(IMG_Exception%s,filename.c_str();break;case 3:strRemoteFile.Format(PTZ_Exc

26、eption%s,filename.c_str();break;case 4:strRemoteFile.Format(PRESET_Exception%s,filename.c_str();break;default:strRemoteFile = filename.c_str();break;/發(fā)送服務器保存路徑,方便后續(xù)存儲trychar inbuff2;char * buf = strRemoteFile.GetBuffer(0);m_SocketClient.Send(buf,MAX_PATH,5);int len = m_SocketClient.Receive(inbuff,2,

27、5);if(len = 0)return 0; /發(fā)送失敗catch (CBlockingSocketException* e)delete(e);return 0;FILE * fstream = fopen(strLocalFile,rb); / 讀取文件數據if ( NULL = fstream )printf( 打開文件失敗,錯誤碼:%d, GetLastError() );return 0;int nNumRead = 0;char temp256;if(NULL != fstream)WaitForSingleObject(m_hMutex,MutexTime_ImageSocke

28、t);printf(開始上傳n);while( !feof( fstream ) )/未到文件末尾,則繼續(xù)發(fā)送nNumRead = fread( temp, 1, 256, fstream );m_SocketClient.Send( temp, nNumRead, 500 );printf(上傳成功n);fclose( fstream );ReleaseMutex(m_hMutex);m_SocketClient.Close();m_SocketClient.Cleanup();return 1;這里首先傳操作標識符,讓服務器準備好接收圖片,然后根據文件名和類型確定服務端的圖片存儲路徑,并傳

29、給服務端然后再分段存儲圖片服務端:cpp view plaincopyprint?1. intReceiveImage(CBlockingSocket&sockCon)2. 3. charszPathMAX_PATH;/獲取本地路徑4. GetCurrentDirectory(MAX_PATH,szPath);5. CStringstrpath(szPath);6. 7. /獲取客戶端傳來的存儲路徑8. charpathtempMAX_PATH;9. intlen=sockCon.Receive(pathtemp,MAX_PATH,5);10. if(len=0)11. return0;12.

30、 else/若獲取成功則返回成功標志位13. 14. charsucflag2=1;15. sockCon.Send(sucflag,2,5);16. 17. CStringfilepath(pathtemp);18. 19. /設置存儲文件路徑20. CStringstrSaveFile;21. strSaveFile.Format(%s%s,strpath,filepath);22. printf(存儲路徑:%sn,strSaveFile);23. 24. CFileFindFinder;/確保本地沒有該文件25. 26. if(Finder.FindFile(strSaveFile)27

31、. 28. 29. DeleteFile(strSaveFile);30. 31. 32. WaitForSingleObject(m_hMutex,MutexTime_ImageSocket);33. FILE*fstream=fopen(strSaveFile,wb);/打開文件操作34. if(NULL=fstream)35. 36. return0;37. 38. 39. /分段接受并存儲文件40. chartemp256;41. intnNumRead=0;42. printf(開始接收圖片n);43. while(true)44. 45. 46. nNumRead=sockCon.

32、Receive(temp,256,500);/文件分段接收47. if(0=nNumRead)/若仍有數據,則持續(xù)接受48. break;49. fwrite(temp,1,nNumRead,fstream);50. 51. 52. ReleaseMutex(m_hMutex);53. printf(圖片接收成功n);54. fclose(fstream);55. return1;56. 57. int ReceiveImage(CBlockingSocket& sockCon)char szPathMAX_PATH;/獲取本地路徑GetCurrentDirectory(MAX_PATH, szPath);CString str

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論