recv () возвращает 0 после того, как сокет получает большие данные

Мой сервер должен отправить клиенту два изображения размером 500 КБ. Клиент получает первое изображение нормально без потери каких-либо данных, но когда сервер отправляет другое изображение клиенту, 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);

Этот код запускается дважды, чтобы получить два изображения.

Когда я ставлю Sleep () после send () на сервер, клиент получает все данные и все изображения, но Sleep зависит от клиентской сети. и сервер получает много клиентов.
Соединение используется с TCP.

2

Решение

recv() возвращает 0, когда другая сторона отключилась изящно. Помните, что TCP — это поток байтов. У него нет концепции сообщений, как у UDP. Скорее всего, ваше второе изображение хранится в том же буфере, который вы используете для первого вызова recv(), Вам необходимо сформировать данные, например, отправить длину файла до того, как отправлять данные файла. Таким образом, получатель может сначала прочитать длину, а затем прочитать столько байтов, сколько говорит длина. Вы пытаетесь это сделать, но не очень хорошо справляетесь с этим. Для начала вы используете строку переменной длины для отправки длины файла. Это не очень хорошая идея, потому что вы не отправляете длину строки, и получатель не ищет нулевой терминатор, поэтому получатель не знает, какова длина строки, и, вероятно, читает слишком много байтов. Вы должны отправить длину файла в виде 4-х байтов фиксированной длины int или 8 байт __int64 вместо. Это будет намного легче для получателя читать.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]