【问题标题】:Error in recv()/send() (in Socket) or read()/write() (in CFile)recv()/send()(在 Socket 中)或 read()/write()(在 CFile 中)中的错误
【发布时间】:2013-08-11 07:13:28
【问题描述】:

我使用底部代码在 2 个客户端之间通过套接字传输文件。 当客户端 A 想向客户端 B 发送文件时,它会将该文件发送到服务器,服务器收到该文件后,将该文件发送给客户端 B。

我的代码用于读取然后发送文件:

CFile f;
BOOL p=f.Open(fname,CFile::modeRead);   
char buff[1024];
int y;
int x;
if(!p)
    //print error msg
while(true)
{       
    y=f.Read(buff,1024);
    x=send(s,buff,y,0);     
    if(y<1024)
    {
        f.Close();
        break;
    }           
}   
send(s, "SENT|",6,0);

我的代码用于接收然后写入文件:

f.Open(fname,CFile::modeCreate | CFile::modeWrite);

while(true)
{       
    z=recv(sRecSocket,buff,512,0);
    if(z==SOCKET_ERROR)
    {
        break;
    }

    if(strncmp(buff,"SENT|",5)==0)
        break;
    f.Write(buff,z);
}   
f.Close();
send(sRecSocket,"RECV|",6,0);

但是当我运行我的项目时,有时它运行良好,文件完全发送到客户端 B,但有时没有,文件发送到客户端 B 但大小为 0 字节或小于文件的实际大小. 有人可以告诉我原因吗? (我英语不好,谢谢你试图理解我在说什么)

【问题讨论】:

  • 您可能希望在尝试发送任何内容之前确保y 大于 大于零。此外,我会建议包含数据长度值的数据包前导码。如所写,您以 1024 字节的块发送并以 512 字节的块接收,但是一旦发送了文件数据(大小为任意),SENT 可以位于任意位置。因此,在 512 字节的边界上寻找它可能不会起作用。
  • 没错!非常感谢!

标签: c++ sockets winapi cfile


【解决方案1】:

send 不保证发送所有提供的数据,recv 也不保证接收所有可用数据。您必须循环调用它们,随时调整剩余数量,每次检查错误,以确保发送或接收所有内容。

凭记忆 - 这些天我总是把循环放在里面! - 循环并不总是必要的(我相信它取决于各种因素,大部分是你无法控制的),所以即使你没有它,你的代码也经常看起来相当可靠。

MSDN documentation for send 中提到了这一点:

如果没有出错,send返回发送的总字节数,可以小于len参数中请求发送的字节数。

【讨论】:

    猜你喜欢
    • 2014-08-17
    • 1970-01-01
    • 2010-12-19
    • 2011-02-04
    • 1970-01-01
    • 2016-08-02
    • 2015-05-31
    • 2011-10-13
    • 1970-01-01
    相关资源
    最近更新 更多