2

我的服务器需要向客户端发送两个大小为 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() 时,客户端会收到所有数据和所有图像,但 Sleep 取决于客户端网络。并且服务器获得了很多客户端。该连接与 TCP 一起使用。

4

1 回答 1

1

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

于 2012-10-06T18:34:52.647 回答