网络编程中粘包的处理方法
写在前面的话:因为自己是才接触网络编程,在工作中第一次遇到粘包问题,我还不知道它是叫粘包问题,所以被整的晕头转向,百思不得其解,自己的代码到底哪里出了问题,最后只能单步调试程序才发现接收方接收到的数据并不一定是按自己设想那样,一次接收整个数据包,当时就想到用文件长度来判断是否接收完文件,之后读了UNP才知道是粘包问题。记录以下当时自己的处理方法。
面对网络编程中的发送文件时的粘包问题,我的处理方法是在要发送文件前,首先发送文件的长度,获取的文件长度是UlongLong类型的整数,发送
时需要转换为字符串,有两种处理方法,第一种是使用C++中的流,第二种是使用系统提供的一个函数,当然第二个是比较方便,但是在知道有第二个
方法前,只能折中采取第一种方法,下面是代码。
第一种方法:
1 // 获取文件长度 2 void CTestCFileLengthDlg::TestFileLength() 3 { 4 CFileDialog dlg(TRUE); 5 6 if(IDOK == dlg.DoModal()) 7 { 8 CString strFilePath = dlg.GetPathName(); 9 CFile file; 10 if(file.Open(strFilePath, CFile::modeRead | CFile::typeBinary)) 11 { 12 ULONGLONG ullLen(0); 13 ullLen = file.GetLength(); 14 CString msg; 15 msg.Format(_T("文件长度为:%llu"), ullLen); 16 17 std::stringstream buffer; 18 buffer << ullLen; 19 char szLength[512] = {0}; 20 memcpy(szLength, buffer.str().c_str(), strlen(buffer.str().c_str())); //Is const char * 21 MessageBox(msg); 22 } 23 else 24 { 25 return ; 26 } 27 } 28 else 29 { 30 return ; 31 } 32 }
第二种方法:
1 // 发送文件长度 2 char szFileLength[21] = {0}; 3 ULONGLONG ullLen(0); 4 CFile file; 5 if(!file.Open(pszFilePath, CFile::modeRead | CFile::typeBinary)) 6 { 7 // 打开文件失败 8 return FALSE; 9 } 10 ullLen = file.GetLength(); 11 _i64toa_s(ullLen, szFileLength, 20, 10); 12 if(SOCKET_ERROR == send(socket, szFileLength, 20, NULL)) 13 { 14 // 发送文件长度失败 15 file.Close(); 16 return FALSE; 17 }