Передача файлов через Winsock
Пытаюсь передать файл используя Winsock и Delphi 2010. Использовал как побайтовую пересылку, так и функцию TransmitFile, на файлах типа .txt, все отлично работает, но при передаче любых других файлов ничего не получается. Я подозреваю, что здесь виноват Unicode с его размерностью, для текстовых файлов использовал 2 байта на символ.
Подскажите пожалуйста как с этим бороться или какой другой способ передачи через Winsock.
А Unicode тут ни при чём
Не знаю, как в вашей ситуации, но у Delphi есть очень удобный набор компонентов Indy, может он вам подойдёт.
Я бы все таки посмотрел на код пересылки пресловутых байтов, а то сейчас мы тут нагадаем...
procedure TServer.TransferFile;
var f: Pwidechar;
hFile: Thandle;
begin
f:='Transfer.txt';
hFile:=CreateFile(f,GENERIC_READ,FILE_SHARE_READ,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
SendData('/*FileName '+f+'*/');
SendData('/\'); //признак начала приема файла
TransmitFile(hsocket,hfile,0,0,nil,nil,0);
SendData('\/'); //признак конца приема файла
CloseHandle(hFile);
end;
Код приема приведу в виде алгоритма так как он займет много места:
1. Когда приходит имя файла создается файл Rewrite(F,1), f: file
2. Когда приходит символ /\ перейти на процедуру приема файла
3. Процедура состоит из проверки размер файла, если равен то завершение процедуры с закрытием файла и сообщением, что файл принят, иначе записываем в файл BlockWrite(f,str,2); где Str: string;
Если использовать функции Filecreate и т.д. результат идентичный.
При передаче текстового файла, размер создаваемого файла, который зависит от количества приходящих строк, равен исходному, но как только передается другой формат, то приходит слишком мало данных, например в .doc приходит всего с десяток байтов, у других видов файлов чуть меньше половины. Совсем сломал голову, что может быть. Потерь в сети быть не может проверял как через IP 127.0.0.1, так и в сети состоящей из хаба и второго компа.
P.S. Всем спасибо за ответы
P.P.S. Видов передачи в TransmitFile похоже нет
if (WSAStartup($0202, wsaData) <> 0) then //Инициализация Winsock 2 версии
begin
Writeln('Unable to start winsock, unable to continue');
Readln;
Exit;
end;
hSocket := Socket(AF_INET, SOCK_STREAM, 0);
Addr.sin_family := AF_INET;
Addr.sin_port := htons(2006);
Addr.sin_addr.S_addr := INADDR_ANY;
Bind(hSocket, Addr, SizeOf(Addr));
if Listen(hSocket, 3)=0 then
begin
iSize := SizeOf(Addr);
while 1>0 do
begin
hRec := Accept(hSocket, @Addr, @iSize);
hFile:= CreateFile('data.djvu', GENERIC_WRITE, FILE_SHARE_WRITE, nil, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
SetFilePointer(hFile, 0, 0, FILE_BEGIN);
l:= recv(hRec, buf, sizeof(buf)-1, 0);
while l>0 do
begin
if (l<0) then break;
WriteFile(hFile, buf, l, &dw, 0);
// writeln(buf);
l:= recv(hRec, buf, sizeof(buf)-1, 0);
end;
CloseHandle(hFile);
MessageBox(0, 'Файл принят.', 'receiver', MB_OK);
closesocket(hRec);
end;
end else Writeln('Error');
Всем спасибо!