晚上用evhttp编了一个http服务器,请求静态文件的时候,发现半天没反应。
vs 2013的调试器也很奇怪,按个F10直接跳到下一个断点了。点击下断点的时候,提示“断点未能绑定”。后来,在网上搜到了解决办法:在 工具 -- 选项 -- 调试 -- 编辑并继续 里面 勾选启用本机“编辑并继续”。
解决了这个问题,就调试一步步跟踪吧。
代码中,先用open打开文件,然后调用evbuffer_add_file将文件内容拷贝到缓冲区。
贴上一段evbuffer_add_file的代码:
while (length) { read = evbuffer_readfile(tmp, fd, (ev_ssize_t)length); if (read == -1) { evbuffer_free(tmp); return (-1); } length -= read; }
这个length最初是用fstat函数计算出来的。 evbuffer_readfile里面调用的是read函数。
调试发现,直到read到文件末尾的时候,这个length还不为0。
疯了,微软的bug吗? open、fstat、read都是crt函数,但是从read读取统计出的大小竟然跟fstat的大小不一样。。。
折腾了半天,写了下面一段代码,测试是不是真的有这个问题。
#include <fcntl.h> #include <share.h> #include <io.h> #include <sys/stat.h> #include <sys/types.h> int _tmain(int argc, _TCHAR* argv[]) { struct _stat buf; int fd; char buffer[1024]; _sopen_s(&fd, "D:\\Code\\httpsvr\\Debug\\ReadMe.txt", O_RDONLY, _SH_DENYWR, 0); _fstat(fd, &buf); int length = buf.st_size; while (length > 0) { int nread = read(fd, buffer, 1024); length -= nread; } close(fd); return 0; }跑起来,果然死循环了。简直不敢相信啊。。。
想来想去,折腾了一个多小时。。
微软可能这么SB吗 感觉不应该吧,再查查msdn。直到看到下面一段解释,才算明白了究竟是怎么回事。。
<p>_ <span style="FONT-WEIGHT: bold">read</span> returns the number of bytes read, which might be less than <span style="FONT-STYLE: italic">count</span> if there are fewer than <span style="FONT-STYLE: italic">count</span> bytes left in the file or if the file was opened in text mode, in which case each carriage return–line feed (CR-LF) pair is replaced with a single linefeed character. Only the single linefeed character is counted in the return value. The replacement does not affect the file pointer.</p>如果是在TEXT模式下打开的,那么_read函数会将CR-LF合并成一个换行符,但保持文件指针位置一致。
把open的模式增加一个_O_BINARY就好了。
_sopen_s(&fd, "D:\\Code\\httpsvr\\Debug\\ReadMe.txt", O_RDONLY | _O_BINARY, _SH_DENYWR, 0);