C C – TCP套接字类:接收问题
我做了自己的Socket类,能够发送和接收HTTP请求.
但我还是遇到了一些问题.以下代码(我的接收函数)仍然有问题,有时会崩溃. 我试过调试它,但它必须在指针算术/内存管理中的某个地方. int Socket::Recv(char *&vpszRecvd) { //vpszRecvd = NULL; int recvsize = 0; char TempBuf[1024]; int Result = 0; char* temp; do { memset(TempBuf,sizeof(TempBuf)); Result = recv( this->sSocket,TempBuf,sizeof(TempBuf) -1,0 ); if (recvsize == 0) recvsize = Result; if ( Result > 0 ) { if ( vpszRecvd != NULL ) { if (temp == NULL) { temp = (char*)calloc(recvsize + 1,sizeof(char)); } else { realloc(temp,recvsize + 1); } if (temp == NULL) return 0; memcpy(temp,vpszRecvd,recvsize); realloc(vpszRecvd,recvsize + Result); if (vpszRecvd == NULL) return 0; memset(vpszRecvd,recvsize + Result); memcpy(vpszRecvd,Result); memcpy(vpszRecvd + recvsize,Result); recvsize += Result; } else { realloc(vpszRecvd,Result); if (vpszRecvd == NULL) return 0; memset(vpszRecvd,Result); memcpy(vpszRecvd,Result); recvsize += Result; } } else if ( Result == 0 ) { return recvsize; } else //if ( Result == SOCKET_ERROR ) { closesocket(this->sSocket); this->sSocket = INVALID_SOCKET; return SOCKET_ERROR; } } while( Result > 0 ); return recvsize; } 有没有人看到任何可能导致崩溃的事情,或者有没有人有更好/更快/更小和更稳定的例子如何通过recv()接收完整数据包? 我不能使用字符串,但必须使用字符. 谢谢你的帮助. 解决方法
你没有初始化temp,最重要的是,你对realloc的调用是错误的.它应该是:
temp = realloc (temp,recvsize+1); 当您按原样调用realloc时,您会丢弃新地址,并且很可能旧地址已被释放.当你试图取消引用时,所有的赌注都会被取消. realloc返回一个新地址的原因是因为如果当前块被包含在存储器领域中,缓冲区的扩展可能需要移动缓冲区(换句话说,它不能只扩展到跟随它的空闲块).在这种情况下,将在场地中创建一个新块,从旧块传输的内容和旧块被释放.如果发生这种情况,您必须从realloc获取返回值. 请记住,realloc不必返回一个新的指针,例如,如果在块之后有足够的可用空间来满足新的大小或者你正在减小大小,它可能会给你相同的指针. 如果它不能扩展块,它也可以返回NULL,你应该注意它,特别是因为: temp = realloc (temp,newsize); 当它返回NULL时会导致内存泄漏(它不会释放旧块). 其他一些事情: >你很少需要使用calloc,特别是在这种情况下,因为你无论如何都要复制内存. 为什么我们不从一些更简单的东西开始?现在,这完全是出于我的想法,所以可能存在一些错误,但它至少会从问题中的内存移动庞然大物中减少:-)所以应该更容易调试. 它基本上分解为: >初始化空消息. >获得一个细分. 代码看起来像这样: int Socket::Recv(char *&vpszRecvd) { int recvsize = 0; char TempBuf[1024]; int Result = 0; char *oldPtr; // Optional free current and initialise to empty. //if (vpszRecvd != NULL) free (vpszRecvd); vpszRecvd = NULL; // Loop forever (return inside loop on end or error). do { Result = recv( this->sSocket,0 ); // Free memory,close socket on error. if (Result < 0) { free (vpszRecvd); closesocket(this->sSocket); this->sSocket = INVALID_SOCKET; return SOCKET_ERROR; } // Just return data and length on end. if (Result == 0) { return recvsize; } // Have new data,use realloc to expand,even for initial malloc. oldPtr = vpszRecvd; vpszRecvd = realloc (vpszRecvd,recvsize + Result); // Check for out-of-memory,free memory and return 0 bytes. if (vpszRecvd == NULL) { free (oldPtr); return 0; } // Append it now that it's big enough and adjust the size. memcpy (&(vpszRecvd[recvsize],Result); recvsize += Result; } while (1); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |