C++中用Socket实现对结构体长字符串和图片的传输_第1页
C++中用Socket实现对结构体长字符串和图片的传输_第2页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、C+中用Socket实现对结构体、长字符串和图片的传输首先说明下,本文的Socket传输引用了CBIockingSocket封装类这个类比较特殊的是Send和Receive的最后一个参数是超时时间,其它与C库里的类似首先说结构体吧,这里传输的结构体含有八个整型,如下cppviewpIaincopyprint?1. typedefstructexceptiontypecount2. intimg_num;3. intptz_num;4. intpreset_num;5. intvideo_num;6. intdevice_num;7. inttotaI_num;8. inttotaI_chann

2、eI;9. intuseIess;10. ExceptionCount,*pExceptionCount;typedefstructexceptiontypecountintimg_num;intptz_num;intpreset_num;intvideo_num;intdevice_num;inttotaI_num;inttotaI_channeI;intuseIess;ExceptionCount,*pExceptionCount;关于Socket的创建和连接这里就不说了,参见点击打开链接这里只说下收发部分的实现服务端:cppviewpIaincopyprint?1.cppviewpIai

3、ncopyprint?1. memset(counttemp,0,256);/青空缓存2. memcpy(counttemp,&ExCount,sizeof(ExCount);将结构体转为字符串3. intcountIen=sockCon.Send(counttemp,256,1000);memset(counttemp,0,256);/青空缓存memcpy(counttemp,&ExCount,sizeof(ExCount);将结构体转为字符串intcountIen=sockCon.Send(counttemp,256,1000);其中,charcountemp256,ExCount是实例化

4、的结构体。客户端:cppviewplaincopyprint?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);intlen=sClient.Receive(countbuff,256,1000);/接受故障数据memset(&count,0,sizeof(count);memcpy(&cou

5、nt,countbuff,sizeof(count);这里的count即为输出的结构体,countbuff同样也是个char256。memset这一步非常重要,如果没有预先清空缓存,就容易出现乱码。字符串:要传一个500K左右的string字符串,肯定不能直接传,因为Socket传输是有字节上限的,好像是16000+字节所以我们采用分段传输的策略服务端:cppviewplaincopyprint?1. sockCon.Send(allSize,allNum.GetLength(),100);2. if(!(sockCon.Receive(resbuff,2,10)3. 4. printf(数据

6、量信息发送失败n);5. return;6. 7. else8. printf(数据量信息发送成功n);9.10.11. temp=AllExDataPtr;12. BytesSent=0;13. while(BytesSentAIIExDataSize)分段传输数据14. 15. intBytesSentThisTime=sockCon.Send(temp,(AllExDataSize-BytesSent)256)?(AllExDataSize-BytesSent):256,1000);16. BytesSent=BytesSent+BytesSentThisTime;17. temp=te

7、mp+BytesSentThisTime;18. sockCon.Send(allSize,allNum.GetLength(),100);if(!(sockCon.Receive(resbuff,2,10)printf(数据量信息发送失败n);return;elseprintf(数据量信息发送成功n);temp=AllExDataPtr;BytesSent=0;while(BytesSentAIIExDataSize)分段传输数据intBytesSentThisTime=sockCon.Send(temp,(AllExDataSize-BytesSent)256)?(AllExDataSiz

8、e-BytesSent):256,1000);BytesSent=BytesSent+BytesSentThisTime;temp=temp+BytesSentThisTime;其中,AIIExDataPtr是指向需要传输的string的一个char*指针,定义为:AIIExDataPtr=(char*)AllExData.c_str();AllSize就是这段数据的字节数,需要首先传到客户端,客户端才可以正常接收客户端:cppviewpIaincopyprint?1. intsizelen=sCIient.Receive(sizebuff,10,50);/接受数据大小2. if(sizeIe

9、n!=0)3. 4. charfIag=1;5. sCIient.Send(fIag,2,10);6. 7. sizebuffsizeIen=0;8. exsize=atoi(sizebuff);9. printf(数据大小:dn,exsize);10. extemp=newcharexsize+256;初始化存储信息的数据,留出冗余空间,以防溢出11. exdata=extemp;/新建指针指向起始地址,方便接收后调用12.12. intBytesReceivedThisTime=0;13. whiIe(BytesReceivedexsize)14. 15. BytesReceivedThi

10、sTime=sCIient.Receive(temp,256,1000);16. strcpy(extemp,temp);17. BytesReceived=BytesReceived+BytesReceivedThisTime;18. extemp=extemp+BytesReceivedThisTime;19. 20. std:stringout=exdata;intsizelen=sCIient.Receive(sizebuff,10,50);/接受数据大小if(sizeIen!=0)charflag=1;sClient.Send(flag,2,10);sizebuffsizelen=0

11、;exsize=atoi(sizebuff);printf(数据大小:dn,exsize);extemp=newcharexsize+256;初始化存储信息的数据,留出冗余空间,以防溢出exdata=extemp;新建指针指向起始地址,方便接收后调用intBytesReceivedThisTime=0;while(BytesReceivedexsize)BytesReceivedThisTime=sClient.Receive(temp,256,1000);strcpy(extemp,temp);BytesReceived=BytesReceived+BytesReceivedThisTime

12、;extemp=extemp+BytesReceivedThisTime;std:stringout=exdata;其中out即为要输出的string,这里建了两个指针指向新建的char数组,其中extemp用于接收时的迭代,exdata用于调用该数组图片:要实现的就是收发图片,这里只写客户端发服务端收的例子,其他均类似客户端:cppviewplaincopyprint?1. intImageSocketClient:UploadFileBySocket(std:stringfilename,inttype)2. 3. CFileFindFinder;/确保本地有该文件4. if(!Finde

13、r.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*flag=str.GetBuffer(0);14.14. if(!m_bConnectOK)/如果Socket没有连接15. 17.try18.19.CSockAddrsaClient(m_strSocketAddress,5858);设IP和端口20.m_Sock

14、etClient.Create();21./创建套接字22.m_SocketClient.Connect(saClient);23./发起连接24.m_SocketClient.Send(flag,str.GetLength(),4);/发送上传标识符25.intlen=m_SocketClient.Receive(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.3

15、7.38.else39.40.try41.42.m_SocketClient.Send(flag,str.GetLength(),4);/发送上传标识符43.intlen=m_SocketClient.Receive(inbuff,2,4);44.if(len=0)45.return0;46.47.catch(CBlockingSocketException*e)48.49.delete(e);50.return0;4./获取本地路径55.charszPathMAX_PATH;56.GetCurrentDirectory(MAX_PATH,szPath);57.CStrin

16、gstrpath(szPath);58.intidx=strpath.ReverseFind(_T();59.if(idx!=strpath.GetLength()-1)如果取后一个字付不是(非根目录),则添加02.103.104.strpath=strpath+;/设置本地路径+文件名CStringstrLocalFile;strLoca

17、lFile.Format(%s%s,strpath,filename.c_str();CStringstrRemoteFile;/服务器保存路径switch(type)case1:strRemoteFile.Format(Preset%s,filename.c_str();break;case2:strRemoteFile.Format(IMG_Exception%s,filename.c_str();break;case3:strRemoteFile.Format(PTZ_Exception%s,filename.c_str();break;case4:strRemoteFile.Forma

18、t(PRESET_Exception%s,filename.c_str();break;default:strRemoteFile=filename.c_str();break;/发送服务器保存路径,方便后续存储trycharinbuff2;char*buf=strRemoteFile.GetBuffer(0);m_SocketClient.Send(buf,MAX_PATH,5);intlen=m_SocketClient.Receive(inbuff,2,5);if(len=0)return0;/发送失败catch(CBlockingSocketException*e)delete(e);

19、return0;105.106.FILE*fstream=fopen(strLocalFile,rb);/读取文件数据107.108. if(NULL=fstream)109. 110. printf(打开文件失败,错误码:d,GetLastError();111. return0;112. 113.114. intnNumRead=0;115. chartemp256;116.116. if(NULL!=fstream)117. 118. WaitForSingleObject(m_hMutex,MutexTime_ImageSocket);119. printf(开始上传n);120. w

20、hile(!feof(fstream)/未到文件末尾,则继续发送121. 122. nNumRead=fread(temp,1,256,fstream);123. m_SocketClient.Send(temp,nNumRead,500);124. 125. printf(上传成功n);126. fclose(fstream);127. ReleaseMutex(m_hMutex);128. 129. m_SocketClient.Close();130. m_SocketClient.Cleanup();131. return1;132. intImageSocketClient:Uplo

21、adFileBySocket(std:stringfilename,inttype)CFileFindFinder;/确保本地有该文件if(!Finder.FindFile(filename.c_str()return-1;/文件未找到charinbuff2;sockType=SOCKET_UPLOAD;/上传操作标志位CStringstr;/将整形标志位转成字符型str.Format(%d,sockType);char*flag=str.GetBuffer(0);if(!m_bConnectOK)/如果Socket没有连接tryCSockAddrsaClient(m_strSocketAdd

22、ress,5858);/设IP和端口m_SocketClient.Create();/创建套接字m_SocketClient.Connect(saClient);/发起连接m_SocketClient.Send(flag,str.GetLength(),4);/发送上传标识符intlen=m_SocketClient.Receive(inbuff,2,4);if(len=0)return0;elsem_bConnectOK=TRUE;/连接成功catch(CBlockingSocketException*e)delete(e);return0;elsetrym_SocketClient.Sen

23、d(flag,str.GetLength(),4);/发送上传标识符intlen=m_SocketClient.Receive(inbuff,2,4);if(len=0)return0;catch(CBlockingSocketException*e)delete(e);return0;/获取本地路径charszPathMAX_PATH;GetCurrentDirectory(MAX_PATH,szPath);CStringstrpath(szPath);intidx=strpath.ReverseFind(_T();if(idx!=strpath.GetLength()-1)如果最后一个字符

24、不是(非根目录),贝V添力口。strpath=strpath+;/设置本地路径+文件名CStringstrLocalFile;strLocalFile.Format(%s%s,strpath,filename.c_str();CStringstrRemoteFile;/服务器保存路径switch(type)case1:strRemoteFile.Format(Preset%s,filename.c_str();break;case2:strRemoteFile.Format(IMG_Exception%s,filename.c_str();break;case3:strRemoteFile.F

25、ormat(PTZ_Exception%s,filename.c_str();break;case4:strRemoteFile.Format(PRESET_Exception%s,filename.c_str();break;default:strRemoteFile=filename.c_str();break;/发送服务器保存路径,方便后续存储trycharinbuff2;char*buf=strRemoteFile.GetBuffer(0);m_SocketClient.Send(buf,MAX_PATH,5);intlen=m_SocketClient.Receive(inbuff,

26、2,5);if(len=0)return0;/发送失败catch(CBlockingSocketException*e)delete(e);return0;FILE*fstream=fopen(strLocalFile,rb);/读取文件数据if(NULL=fstream)printf(打开文件失败,错误码:d,GetLastError();return0;intnNumRead=0;chartemp256;if(NULL!=fstream)WaitForSingleObject(m_hMutex,MutexTime_ImageSocket);printf(开始上传n);while(!feof

27、(fstream)/未到文件末尾,则继续发送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();return1;这里首先传操作标识符,让服务器准备好接收图片,然后根据文件名和类型确定服务端的图片存储路径,并传给服务端然后再分段存储图片服务端:cppviewplaincopyprint?1.intRec

28、eiveImage(CBlockingSocket&sockCon).charszPathMAX_PATH;/获取本地路径GetCurrentDirectory(MAX_PATH,szPath);CStringstrpath(szPath);/获取客户端传来的存储路径charpathtempMAX_PATH;intlen=sockCon.Receive(pathtemp,MAX_PATH,5);if(len=0)return0;else/若获取成功则返回成功标志位charsucflag2=1;sockCon.Send(sucflag,2,5);CStringfilepath(pa

29、thtemp);/设置存储文件路径CStringstrSaveFile;strSaveFile.Format(%s%s,strpath,filepath);printf(存储路径:sn,strSaveFile);CFileFindFinder;/确保本地没有该文件if(Finder.FindFile(strSaveFile)DeleteFile(strSaveFile);WaitForSingleObject(m_hMutex,MutexTime_ImageSocket);FILE*fstream=fopen(strSaveFile,wb);/打开文件操作if(NULL=fstream)ret

30、urn0;/分段接受并存储文件chartemp256;intnNumRead=0;printf(开始接收图片n);while(true)nNumRead=sockCon.Receive(temp,256,500);文件分段接收if(0=nNumRead)/若仍有数据,则持续接受break;9.50.fwrite(temp,1,nNumRead,fstream);51. 52. ReleaseMutex(m_hMutex);53. printf(图片接收成功n);54. fclose(fstream);55. return1;56.56. intReceiveImage(CBlockingSocket&sockCon)charszPathMAX_PATH;/获取本地路径GetCurrentDirectory(MAX_PATH,szPath);C

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论