user-0 提问: 100分悬赏！！！在线等！！！

回复:
user: user-0
content: 引用 79 楼 sagittarius_520 的回复:[quote=引用 77 楼 Zidane_2014 的回复:] [quote=引用 75 楼 sagittarius_520 的回复:] [quote=引用 74 楼 Zidane_2014 的回复:] [quote=引用 71 楼 sagittarius_520 的回复:] 最后一个字符不是EOF吗？读到最后一个字符的时候你的while()循环判断失败了直接跳出去了，while(length=recv(client_socket,buf,BUFFERSIZE,0))这里面的循环根本不会执行啊，所以才会导致少了一个字节。 你可以在while里面加一个判断试试，里面这句话应该不会输出的。 	 if (length == EOF) 	{ 		printf("file end!\n"); 	} 但是跳出了之后不应该继续后面的代码吗？？顺序执行会打印“success”呀。但问题是卡在那里，不来也不去。[/quote] printf()后面的代码都没有执行吗？[/quote]请看70楼的调试图。第一张图指明了程序停止（不能说停止，可能说卡在那里更合适）的地方。[/quote] 我个人认为你这while循环的判断while(length=recv(client_socket,buf,BUFFERSIZE,0))有问题，recv读取到最后一个字节的时候返回值并不是0吧？而是1，因为读取最后一个字节的时候recv还是读取到了东西，读取的是'\0'这个描述符，所以所length的值不为0，while循环继续，那么也就会出现你所说的读取到了不可能出现的字符。可以试着在while循环里面对length进行一个判断，如果为0则跳出循环。这可能就是程序为什么会一直卡死在while循环里面。[/quote]恩！我今晚上试一试。

user: user-0
content: 引用 76 楼 lovesmiles 的回复:看你的截图，数据全部收到了buff了吧。你是不是经常用ctrl^D来结束程序？       int write_length=fwrite(buf,sizeof(char),length,fp);         if(write_length<length)         {             printf("Write Failed!\n");             break;         } 改成这样子试一下：        int write_length=fwrite(buf,sizeof(char),length,fp); flush(fp);//fwrite之后马上刷新缓存看看。         if(write_length<length)         {             printf("Write Failed!\n");             break;         } 引用 78 楼 lovesmiles 的回复:fflush(fp);两个都是大神！！！终于解决了文件传输的问题。现在终于能够收到完整的文件了！！但是客户端一直会卡在"Finished"那里。不知道为什么。我准备写一个判断文件结尾的语句来break，不知道行不行？

user: user-1
content: 引用 80 楼 Zidane_2014 的回复:[quote=引用 76 楼 lovesmiles 的回复:] 看你的截图，数据全部收到了buff了吧。你是不是经常用ctrl^D来结束程序？       int write_length=fwrite(buf,sizeof(char),length,fp);         if(write_length<length)         {             printf("Write Failed!\n");             break;         } 改成这样子试一下：        int write_length=fwrite(buf,sizeof(char),length,fp); flush(fp);//fwrite之后马上刷新缓存看看。         if(write_length<length)         {             printf("Write Failed!\n");             break;         } 引用 78 楼 lovesmiles 的回复:fflush(fp);两个都是大神！！！终于解决了文件传输的问题。现在终于能够收到完整的文件了！！但是客户端一直会卡在"Finished"那里。不知道为什么。我准备写一个判断文件结尾的语句来break，不知道行不行？[/quote]  再说一次，请在客户端也使用select 模型。

user: user-0
content: 引用 82 楼 lovesmiles 的回复:[quote=引用 80 楼 Zidane_2014 的回复:] [quote=引用 76 楼 lovesmiles 的回复:] 看你的截图，数据全部收到了buff了吧。你是不是经常用ctrl^D来结束程序？       int write_length=fwrite(buf,sizeof(char),length,fp);         if(write_length<length)         {             printf("Write Failed!\n");             break;         } 改成这样子试一下：        int write_length=fwrite(buf,sizeof(char),length,fp); flush(fp);//fwrite之后马上刷新缓存看看。         if(write_length<length)         {             printf("Write Failed!\n");             break;         } 引用 78 楼 lovesmiles 的回复:fflush(fp);两个都是大神！！！终于解决了文件传输的问题。现在终于能够收到完整的文件了！！但是客户端一直会卡在"Finished"那里。不知道为什么。我准备写一个判断文件结尾的语句来break，不知道行不行？[/quote]  再说一次，请在客户端也使用select 模型。[/quote]我加了个if判断语句，现在可以执行完整程序了。谢谢指导！！

user: user-2
content: 二进制方式读取, 二进制方式传送,  二进制方式写入.  你的问题应该是数据本身就有问题了.  你先试试发送一个自己在内存中构造的buffer, 看能否正常发送和接收. 如果能, 那就是你读取的数据有问题了.

user: user-0
content: 引用 46 楼 zilaishuichina 的回复:那就是recv返回0了嘛， socket被关掉了， 然后length=0， while条件不成立，循环直接结束了，然后你后面打印的还是success  你可以这样写       int length=0;     while(true)     {         length=recv(client_socket,buf,BUFFERSIZE,0)          if(length==0)         {             printf("socket closed!\n");             break;         }          if(length<0)         {             printf("Receive Data Failed!\n");             break;         }                   int write_length=fwrite(buf,sizeof(char),length,fp);         if(write_length<length)         {             printf("Write Failed!\n");             break;         }         bzero(buf,BUFFERSIZE);     }改成这样，连数据都收不到了。运行程序后，程序就一直卡在"Finished!"这里。

user: user-1
content: 我说，你改成select IO试下嘛。为什么一定要用一个阻塞的read呢？还把它放到一个while里面。

user: user-3
content: 那就是recv返回0了嘛， socket被关掉了， 然后length=0， while条件不成立，循环直接结束了，然后你后面打印的还是success  你可以这样写       int length=0;     while(true)     {         length=recv(client_socket,buf,BUFFERSIZE,0)          if(length==0)         {             printf("socket closed!\n");             break;         }          if(length<0)         {             printf("Receive Data Failed!\n");             break;         }                   int write_length=fwrite(buf,sizeof(char),length,fp);         if(write_length<length)         {             printf("Write Failed!\n");             break;         }         bzero(buf,BUFFERSIZE);     }

user: user-0
content: 引用 44 楼 zilaishuichina 的回复:那就是不止1字节， 这显然不止1字节  如果lz确认抓包了， 服务端发来的数据是有最后的 </dev> </devices> </msg> 这些内容的  那么可能就是recv的问题了， 比如设置的是阻塞还是非阻塞， 比如是不是你这边还在循环recv中，对端已经close了而不是shutdown  lz实际出问题的代码，应该不是lz现在贴出来的代码吧代码绝对是这个代码。 我用了wireshark抓包后follow TCP stream，显示的结尾：  说明服务端是传过来的。 我现在正在gdb那个while循环，看每一次的结果。

user: user-4
content: 引用 22 楼 Zidane_2014 的回复:如何能避免死循环呢？ 让服务器端关闭套接字就好了，这样recv返回就是0了。send.xml就算是发给服务器，你接收的时候，是按你给定的缓冲区大小来接收的，如果缓冲大小小于实际大小，就只返回缓冲区大小的内容。所以我想你看下send.xml里的字节数是不是比BUFFERSIZE大了

user: user-3
content: 那就是不止1字节， 这显然不止1字节  如果lz确认抓包了， 服务端发来的数据是有最后的 </dev> </devices> </msg> 这些内容的  那么可能就是recv的问题了， 比如设置的是阻塞还是非阻塞， 比如是不是你这边还在循环recv中，对端已经close了而不是shutdown  lz实际出问题的代码，应该不是lz现在贴出来的代码吧

user: user-0
content: 引用 40 楼 zilaishuichina 的回复:[quote=引用 38 楼 Zidane_2014 的回复:] [quote=引用 36 楼 zilaishuichina 的回复:] [quote=引用 35 楼 Zidane_2014 的回复:] [quote=引用 30 楼 zilaishuichina 的回复:] [quote=引用 29 楼 Zidane_2014 的回复:] [quote=引用 25 楼 mymtom 的回复:] 查下少了哪个字节啊，这样可以帮助判断错误的原因。  引用 27 楼 zilaishuichina 的回复:少一个字节 少的是什么？ 是最后一个‘〉’么？ 是不是任意一个文件都是少最后这个字符？  引用 28 楼 WizardOz 的回复:跟本就没有EOF这个字符，EOF只是函数的返回值而已，如果少了一个字符，可能是少了'\r'之类的，建议LZ把文件内容用16进制的方式打印出来，这样看的最清楚，到底少了什么。左边是正常情况，12289bytes。右边是不正常的情况，12288bytes。 正常结尾: 不正常结尾：[/quote]  </dev> </devices> </msg> 这个显然不是少1字节吧[/quote]??  size显示是不准确的吗？[/quote]  不一定是size不准确， 而是我们眼睛看到的字符，不一定就是文件里面实际有的字符，你后面没显示出来的内容，有可能是空格呀，回车符啊，换行符啊，ASCII表里面并不是每一个字符都能在文本当中显示出来的呀。 [/quote]恩。也就是说，size显示的是能看到的大小？[/quote]  size显示的是真实大小（包括那些看不见的字符），你建个空文本，按10次enter键，你看到的文本内容可能什么也没有，但是你看文件的size可能是20字节  所以你的例子里面，在xml里面看到的内容缺的不止一个字节，但是size显示少一个字节，也就是说明你看到内容后面还跟着一些你看不到的内容，所以需要用16进制显示，这样才能把看不到的内容也显示出来，这样才能知道这些看不到的内容具体是什么字符，然后最后缺了一个什么字符.  [/quote]用Bcompare比较了下：  history行的16进制： dev行的16进制： devices行的16进制： msg行的16进制：

user: user-3
content: 引用 39 楼 Zidane_2014 的回复:引用 37 楼 user-4 的回复:你在服务器端，也保存一个文件看看，是同样少字节还是完整的。要是完整的就把服务器端的接收代码改改弄到客户端。要还出错，那服务器端发送就有问题了服务端我接触不到。  你可以模拟一个服务端， 把你代码里面接受，和发送的代码分成两个程序来测试

user: user-4
content: 引用 39 楼 Zidane_2014 的回复:服务端我接触不到。 额，你调试的时候，查看客户端recv函数写入buf里的内容是完整的么，还是说那里就已经缺失了。要是这样的话，服务器返给你的数据就少了。

user: user-3
content: 引用 38 楼 Zidane_2014 的回复:[quote=引用 36 楼 zilaishuichina 的回复:] [quote=引用 35 楼 Zidane_2014 的回复:] [quote=引用 30 楼 zilaishuichina 的回复:] [quote=引用 29 楼 Zidane_2014 的回复:] [quote=引用 25 楼 mymtom 的回复:] 查下少了哪个字节啊，这样可以帮助判断错误的原因。 引用 27 楼 zilaishuichina 的回复:少一个字节 少的是什么？ 是最后一个‘〉’么？ 是不是任意一个文件都是少最后这个字符？ 引用 28 楼 WizardOz 的回复:跟本就没有EOF这个字符，EOF只是函数的返回值而已，如果少了一个字符，可能是少了'\r'之类的，建议LZ把文件内容用16进制的方式打印出来，这样看的最清楚，到底少了什么。左边是正常情况，12289bytes。右边是不正常的情况，12288bytes。 正常结尾: 不正常结尾：[/quote]  </dev> </devices> </msg> 这个显然不是少1字节吧[/quote]??  size显示是不准确的吗？[/quote]  不一定是size不准确， 而是我们眼睛看到的字符，不一定就是文件里面实际有的字符，你后面没显示出来的内容，有可能是空格呀，回车符啊，换行符啊，ASCII表里面并不是每一个字符都能在文本当中显示出来的呀。 [/quote]恩。也就是说，size显示的是能看到的大小？[/quote]  size显示的是真实大小（包括那些看不见的字符），你建个空文本，按10次enter键，你看到的文本内容可能什么也没有，但是你看文件的size可能是20字节  所以你的例子里面，在xml里面看到的内容缺的不止一个字节，但是size显示少一个字节，也就是说明你看到内容后面还跟着一些你看不到的内容，所以需要用16进制显示，这样才能把看不到的内容也显示出来，这样才能知道这些看不到的内容具体是什么字符，然后最后缺了一个什么字符.

user: user-0
content: 引用 37 楼 user-4 的回复:你在服务器端，也保存一个文件看看，是同样少字节还是完整的。要是完整的就把服务器端的接收代码改改弄到客户端。要还出错，那服务器端发送就有问题了服务端我接触不到。

user: user-0
content: 引用 36 楼 zilaishuichina 的回复:[quote=引用 35 楼 Zidane_2014 的回复:] [quote=引用 30 楼 zilaishuichina 的回复:] [quote=引用 29 楼 Zidane_2014 的回复:] [quote=引用 25 楼 mymtom 的回复:] 查下少了哪个字节啊，这样可以帮助判断错误的原因。 引用 27 楼 zilaishuichina 的回复:少一个字节 少的是什么？ 是最后一个‘〉’么？ 是不是任意一个文件都是少最后这个字符？ 引用 28 楼 WizardOz 的回复:跟本就没有EOF这个字符，EOF只是函数的返回值而已，如果少了一个字符，可能是少了'\r'之类的，建议LZ把文件内容用16进制的方式打印出来，这样看的最清楚，到底少了什么。左边是正常情况，12289bytes。右边是不正常的情况，12288bytes。 正常结尾: 不正常结尾：[/quote]  </dev> </devices> </msg> 这个显然不是少1字节吧[/quote]??  size显示是不准确的吗？[/quote]  不一定是size不准确， 而是我们眼睛看到的字符，不一定就是文件里面实际有的字符，你后面没显示出来的内容，有可能是空格呀，回车符啊，换行符啊，ASCII表里面并不是每一个字符都能在文本当中显示出来的呀。 [/quote]恩。也就是说，size显示的是能看到的大小？

user: user-4
content: 你在服务器端，也保存一个文件看看，是同样少字节还是完整的。要是完整的就把服务器端的接收代码改改弄到客户端。要还出错，那服务器端发送就有问题了

user: user-3
content: 引用 35 楼 Zidane_2014 的回复:[quote=引用 30 楼 zilaishuichina 的回复:] [quote=引用 29 楼 Zidane_2014 的回复:] [quote=引用 25 楼 mymtom 的回复:] 查下少了哪个字节啊，这样可以帮助判断错误的原因。 引用 27 楼 zilaishuichina 的回复:少一个字节 少的是什么？ 是最后一个‘〉’么？ 是不是任意一个文件都是少最后这个字符？ 引用 28 楼 WizardOz 的回复:跟本就没有EOF这个字符，EOF只是函数的返回值而已，如果少了一个字符，可能是少了'\r'之类的，建议LZ把文件内容用16进制的方式打印出来，这样看的最清楚，到底少了什么。左边是正常情况，12289bytes。右边是不正常的情况，12288bytes。 正常结尾: 不正常结尾：[/quote]  </dev> </devices> </msg> 这个显然不是少1字节吧[/quote]??  size显示是不准确的吗？[/quote]  不一定是size不准确， 而是我们眼睛看到的字符，不一定就是文件里面实际有的字符，你后面没显示出来的内容，有可能是空格呀，回车符啊，换行符啊，ASCII表里面并不是每一个字符都能在文本当中显示出来的呀。

user: user-0
content: 引用 30 楼 zilaishuichina 的回复:[quote=引用 29 楼 Zidane_2014 的回复:] [quote=引用 25 楼 mymtom 的回复:] 查下少了哪个字节啊，这样可以帮助判断错误的原因。 引用 27 楼 zilaishuichina 的回复:少一个字节 少的是什么？ 是最后一个‘〉’么？ 是不是任意一个文件都是少最后这个字符？ 引用 28 楼 WizardOz 的回复:跟本就没有EOF这个字符，EOF只是函数的返回值而已，如果少了一个字符，可能是少了'\r'之类的，建议LZ把文件内容用16进制的方式打印出来，这样看的最清楚，到底少了什么。左边是正常情况，12289bytes。右边是不正常的情况，12288bytes。 正常结尾: 不正常结尾：[/quote]  </dev> </devices> </msg> 这个显然不是少1字节吧[/quote]??  size显示是不准确的吗？