Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Передача файлов через Winsock

56K
18 марта 2010 года
Hekeus
8 / / 18.03.2010
Доброго времени суток.
Пытаюсь передать файл используя Winsock и Delphi 2010. Использовал как побайтовую пересылку, так и функцию TransmitFile, на файлах типа .txt, все отлично работает, но при передаче любых других файлов ничего не получается. Я подозреваю, что здесь виноват Unicode с его размерностью, для текстовых файлов использовал 2 байта на символ.
Подскажите пожалуйста как с этим бороться или какой другой способ передачи через Winsock.
7
19 марта 2010 года
@pixo $oft
3.4K / / 20.09.2006
Может,там есть режимы бинарный и текстовый(как в FTP)?Посмотрите
А Unicode тут ни при чём
253
19 марта 2010 года
Proger_XP
1.5K / / 07.08.2004
Не знаю, как в вашей ситуации, но у Delphi есть очень удобный набор компонентов Indy, может он вам подойдёт.
303
19 марта 2010 года
makbeth
1.0K / / 25.11.2004
Я бы все таки посмотрел на код пересылки пресловутых байтов, а то сейчас мы тут нагадаем...
56K
20 марта 2010 года
Hekeus
8 / / 18.03.2010
Код побайтовой передачи я давно затер, так как он не давал высокой скорости, конечно можно было увеличить скорость, но зачем если есть функция TransmitFile, поэтому и решил остановится на ней. Насчет, Indy компонентов не сказал бы, что в программе их использовать нельзя, но смысл? Практически все что мне нужно реализовано на Winsock, а вот пересылка файлов пока не дается, я подумал не проблема ли в том, что TransmitFile пересылает информацию в байтах, или еще в чем, а я ведь ее просто в символьных значениях принимаю, сейчас буду пробовать, к сожалению в MSDN ничего не написано про принимающую сторону. Код отправления:

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 похоже нет
56K
23 марта 2010 года
Hekeus
8 / / 18.03.2010
Воспроизвел для проверки участок кода передачи данных, принимающую и отправляющую сторону, и совершенно случайно наткнулся на источник проблемы, он оказался в коде принимающей стороны, а вся проблема была в строчке после записи в файл, а именно Writeln(buf);. Закомментировав ее все отлично заработало. В чем был глюк я так и не понял, если кто знает объясните пожалуйста, а код принимающей стороны приведу ниже:

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

Всем спасибо!
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог