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

问题描述 投票:2回答:1

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

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

服务器:

    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);

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

客户:

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一起使用。

c++ sockets send recv
1个回答
1
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.