Winsock Передача Файла

alekssgor

Well-known member
26.05.2008
118
0
#1
Как передать файл больше 2 гигабайт. Передаю с помощью функции TransmitFile????????
Вот пример клиент отправляет файл серверу

Клиент
Код:
	char szMessage[1024];
strcpy(szMessage, "Transferfilestart");
//Отправка команды о начале передачи файла
ret = send(sClient, szMessage, strlen(szMessage), 0);
if(ret == SOCKET_ERROR)
MessageBoxA(0, "Ошибка при выполнении функции send", "Клиент", 0);
//Задержка
Sleep(1000);
//Получение данных
char szRecvBuff[1024];
ret = recv(sClient, szRecvBuff, 1024, 0);
if(ret == SOCKET_ERROR)
MessageBoxA(0, "Ошибка ппри получении данных", "Клиент", 0);
if(strstr(szRecvBuff, "transferfileok"))
{
MessageBoxA(0, "Сервер согласился принять файл\nНачало передачи файла", "Клиент", 0);
HANDLE h;
if((h = CreateFileA("che.avi", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_OVERLAPPED, NULL)) == INVALID_HANDLE_VALUE)
{
MessageBoxA(0,"Ошибка при открытии файла","Клиент",0);
}
//Передача файла пакетами по 64000 байт
if(! TransmitFile(sClient, h, 0, 64000, NULL, NULL, TF_USE_DEFAULT_WORKER ))
{
MessageBoxA(0, "Ошибка при передачи файла", "Клиент", 0);
}
//TransmitFile(sClient, h, 200000, 64000, NULL, NULL, TF_USE_DEFAULT_WORKER );
//TransmitFile(sClient, h, 294965248, 64000, NULL, NULL, TF_USE_DEFAULT_WORKER );
CloseHandle(h);	
}
//Отправка команды о завершении отправки файла
strcpy(szMessage, "Transferfilefinish");
ret = send(sClient, szMessage, strlen(szMessage), 0);
if(ret == SOCKET_ERROR)
MessageBoxA(0, "Ошибка при выполнении функции send", "Клиент", 0);

closesocket(sClient);
Сервер
Код:
//Получение данных
char szRecvBuff[64000], szSendBuff[1024];
ret = recv(sock, szRecvBuff, 64000, 0);
//Проверка полученных данных
if(ret == 0) break;
else if(ret == SOCKET_ERROR)
{
MessageBoxA(0, "Ошибка при получении данных", "Сервер", 0);
break;
}
szRecvBuff[ret] = '\0';
//Здесь можно поставить проверку принятого текста
//в переменной szRecvBuff
if(strstr(szRecvBuff, "Transferfilestart"))
{
MessageBoxA(0, "Запрос о передачи файла от клиента", "Сервер", 0);
//Отправка согласия о приёме файла от клиента
strcpy(szSendBuff, "transferfileok");
//Отправка содержимого переменной szSendBuff клиенту
ret = send(sock, szSendBuff, strlen(szSendBuff), 0);
if(ret == SOCKET_ERROR) break; 

}
//Получение данных
ret = recv(sock, szRecvBuff, 64000, 0);
//Проверка полученных данных
if(ret == 0) break;
else if(ret == SOCKET_ERROR)
{
MessageBoxA(0, "Ошибка при получении данных", "Сервер", 0);
break;
}
//szRecvBuff[ret] = '\0';
HANDLE h;
DWORD BWritten;
if((h = CreateFileA("che.avi", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE)
{
MessageBoxA(0, "Ошибка при создании файла", "Сервер", 0);  
}
while(!strstr(szRecvBuff, "Transferfilefinish"))
{
WriteFile(h, szRecvBuff, ret, &BWritten, NULL);
//Получение очередного пакета данных
ret = recv(sock, szRecvBuff, 64000, 0);	
}
CloseHandle(h);

if(strstr(szRecvBuff, "Transferfilefinish"))
{
MessageBoxA(0, "Файл принят", "Сервер", 0);
break;
}
 
A

artkl

#2
При передаче возникает какая-нибудь ошибка? Если да, то опишите ее подробно.
 

alekssgor

Well-known member
26.05.2008
118
0
#3
При передаче возникает какая-нибудь ошибка? Если да, то опишите ее подробно.
Сама функция TransmitFile за один вызов может отправлять 2147483646 байт что соответствует 1,99 гбайт
третий параметр функции указывает число байт передаваемых из файла(но не более этого числа) Если указать ноль то отправляется весь файл но если файл не больше этого числа если больше отправка даже не начинается а выдаётся ошибка . С этим всё понятно
На msdn
Для просмотра контента необходимо: Войти или зарегистрироваться

говорится что при повторном вызове функции можно передать файл большего размера не могу только разобратся как???

Мне кажется проблема в параметрах открытии файла
CreateFileA("che.avi", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_OVERLAPPED, NULL)
При онократном вызове функции и отправки файла до 2гбайт всё работает!!!