C套接字仅使用二进制数据进行内存泄漏
我正在编写一个web代理,它可以很好地处理可以转换为ASCII文本的网页。但是,当我试图查看包含二进制数据的页面时(Youtube.com就是我一直使用的页面),某个地方出现了内存泄漏,同样的几个字符会在我发送给客户端的字符串末尾反复出现(并且会出现在其他明显不应该出现的地方) 下面是我代码的相关部分。SendHTTPResponse是一个使用代理向客户端发送网页响应的函数,它可以正常工作 有人有什么见解吗C套接字仅使用二进制数据进行内存泄漏,c,sockets,http,binary-data,C,Sockets,Http,Binary Data,我正在编写一个web代理,它可以很好地处理可以转换为ASCII文本的网页。但是,当我试图查看包含二进制数据的页面时(Youtube.com就是我一直使用的页面),某个地方出现了内存泄漏,同样的几个字符会在我发送给客户端的字符串末尾反复出现(并且会出现在其他明显不应该出现的地方) 下面是我代码的相关部分。SendHTTPResponse是一个使用代理向客户端发送网页响应的函数,它可以正常工作 有人有什么见解吗 int numBytes; char temp[3000]; memset(temp
int numBytes;
char temp[3000];
memset(temp, '\0', 3000);
numBytes = Read(internetSocket, temp, 2999);
while (errno = 0, numBytes > 0 || errno == EINTR)
{
SendHTTPResponse(socket, temp, numBytes);
memset(temp, '\0', 3000);
numBytes = Read(internetSocket, temp, 2999);
}
为了回答您的问题,此代码中没有内存泄漏 也没有理由认为内存泄漏与此问题有关 然而,您的代码是错误的。它不应该设置
errno
,也不应该测试它,除非该方法返回-1。应改为:
while ((numBytes = Read(socket, temp, sizeof temp)) > 0 || numBytes == -1 && errno == EINTR)
{
SendHTTPResponse(socket, temp, numBytes);
}
您不需要memset()
调用,也不需要为后面的null留出任何空间,只要SendHTTPResponse()
正确地注意到您传递它的长度。它当然不应该寻找尾随的null本身
3000是一个非常奇怪的缓冲区大小。我自己会用8192。这只是一个关于你问题的有根据的猜测。正如其他人所说,您没有发布足够的信息来查找错误
二进制数据和文本数据之间最大的区别在于前者(编辑,谢谢EJP)可以包含空('\0')字节。如果您使用的是字符串函数(例如strlen()),它们会将这些函数解释为字符串的结尾,因此您将丢失数据。这里没有足够的信息或代码来回答此问题。您需要进行一些调试并缩小范围。您是否必须接受numBytes==0作为有效的返回值,这意味着缓冲区中没有任何内容,但流仍然打开&您应该继续尝试读取?errno=0,numBytes>0????那是什么?你为什么这样使用逗号运算符?为什么要将errno设置为0?@ThomasW
numBytes==0
表示对等方已断开连接,您不应该继续尝试读取。@ThomasW man recv()将是一个很好的开始,您不认为吗?这不是Java。前者可以包含空字节。如果numBytes
为-1,则不应调用SendHTTPResponse()
,因为没有要发送的数据,但当errno
为EINTR
时,应再次调用Read()
以保持读取。我将使用do/while
循环,然后在Read()
实际失败时使用break
。