首页 文章

在socket接收大数据后,recv()返回0

提问于
浏览
2

我的服务器需要向客户端发送两个大小为500kb的图像 . 客户端在没有丢失任何数据的情况下接收第一个图像,但是当服务器将另一个图像发送到客户端时,recv()在从服务器发送数据之前返回0,并且在此之后服务器send()返回-1 .

这是我的send()和recv()代码:

Server:

fp2 = fopen(totaldir2,"rb");
if(fp1==NULL)
{
    cout<<"ERROR while openning: "<<totaldir2<<endl;
    getchar();
    exit(1);
}

fseek (fp2, 0 , SEEK_END);
IFileSize2 = ftell (fp2);
rewind (fp2);
picture2 = new char[sizeof(char)*IFileSize2+1];
if (picture2 == NULL) {exit (2);}
itoa (IFileSize2,CFileSize2,10);
countData = 0;
do{
sentData = send(sConnect,CFileSize2,strlen(CFileSize2)+1,NULL);
countData+=sentData;
}while(countData<strlen(CFileSize2)+1);
read = fread_s(picture2, IFileSize2, sizeof(char),IFileSize2, fp2);
countData = 0;
do{
sentData = send(sConnect, picture2, read, 0);
countData += sentData ;
}while(countData<read);

此代码运行两次以发送两个图像 .

Client:

recv(sConnect, len2, sizeof(len2) ,NULL); \\recv returns 0 here before server sends the data.
FileSize2 = atoi(len2);
picture2 = new char[sizeof(char)*FileSize2+1];
fp2 = fopen("temp\\image2.bin","wb");
if(fp2==NULL)
{
     closesocket(sConnect);
     WSACleanup();
     exit(1);
    }

recv(sConnect, picture2, FileSize2, 0); \\same here
fwrite(picture2, sizeof(char), Received2, fp2);

此代码运行两次以接收两个图像 .

当我在服务器中的send()之后放入Sleep()时,客户端会接收所有数据和所有图像,但睡眠取决于客户端网络 . 并且服务器获得了很多客户端 . 该连接与TCP一起使用 .

1 回答

  • 1

    当对方正常断开连接时 recv() 返回0 . 请记住,TCP是一个字节流 . 它没有UDP这样的消息概念 . 最有可能的是,您的第二个图像存储在您用于第一次调用 recv() 的同一个缓冲区中 . 您需要构建数据框架,例如在发送文件数据之前发送文件的长度 . 这样,接收器可以先读取长度,然后只读取长度所说的字节数 . 你正试图这样做,但你没有很好地管理它 . 对于初学者,您使用可变长度字符串来发送文件长度 . 这不是一个好主意,因为您没有发送字符串长度,并且接收器不寻找空终止符,因此接收器不知道字符串有多长并且可能读取太多字节 . 您应该将文件长度发送为固定长度的4字节 int 或8字节 __int64 . 接收器读取起来会容易得多 .

相关问题