Форум: "Сети";
Текущий архив: 2009.03.29;
Скачать: [xml.tar.bz2];
ВнизКак правильно послать файл через TcpServer & TcpClient ? Найти похожие ветки
← →
Andrewtitoff © (2008-01-21 12:40) [40]>Теперь разнеси своего клиента и сервера по разным углам Тырнета и попытайся передать файл размером более 8 кб
Вот блин точно..., Len в ReceiveBuf(buf^,len,0); имеет тип word, а он равен 2 байтам т.е. от 0 до 65535... =((( , а что что бы послать файл побольше его нужно разбивать, или есть какой нить способ?
>Или попытайся обслужить более чем одного клиента одновременно
А как сделать то??, хотя для задачи которая на данный момент передомной стоит мне вполне хватит две пары клиент-сервер, но все таки хотелось бы знать и как сделать с несколькими клиентами... =(((
← →
Сергей М. © (2008-01-21 13:12) [41]
> Len в ReceiveBuf(buf^,len,0); имеет тип word
Ничего подобного.
В твоей декларации он integer и в прототипе oн тоже integer, так что верхний предел 2гб.
Да и не в этом дело.
А дело в том, что результат выполнения ReceiveBuf вовсе не обязан быть равным значению Len - он может быть и меньшим чем Len, вплоть до 0 или -1. Ты этот факт в своем коде никак не учитываешь, потому и грабли тебе обеспечены. Я же сказал тебе - анализируй результат !
← →
Сергей М. © (2008-01-21 13:14) [42]
> Canvas does not allow drawing
Убирай ShowMessage.
← →
Andrewtitoff © (2008-01-21 13:53) [43]А точно, гдето я не там высмотрел, все верно integer... =)))
>А дело в том, что результат выполнения ReceiveBuf вовсе не обязан быть равным значению Len - он может быть и меньшим чем Len, вплоть до 0 или -1. Ты этот факт в своем коде никак не учитываешь, потому и грабли тебе обеспечены. Я же сказал тебе - анализируй результат !
Вот блин я написал
var
asd:tmemorystream;
len:integer;
LenRes:integer;
buf:pointer;
begin
len:=68096;
asd:=TMemoryStream.Create;
GetMem(buf,len);
LenRes:=ClientSocket.ReceiveBuf(buf^,len);
asd.Position:=0;
asd.WriteBuffer(buf^,len);
if LenRes <> len then
ShowMessage("Ошибка размера : "+Inttostr(LenRes))
else
begin
asd.SaveToFile("c:\000.doc");
ShowMessage("Файл принят")
end;
asd.Free;
FreeMem(Buf);
end;
Теперь прога виснет и неодного мессаджа не показывает... =((((
← →
Andrewtitoff © (2008-01-21 13:55) [44]Опять ShowMessage?, а почему, при чем тут оно?, и чем можно тогда выводить сообщения?
← →
Сергей М. © (2008-01-21 13:58) [45]Ты по-русски читать умеешь ?
Сказано же - убирай к чертовой бабушке все свои ShowMessage !)
Нельзя в доп.потоке обращаться визуальным VCL-контролам !
← →
Сергей М. © (2008-01-21 14:00) [46]
> чем можно тогда выводить сообщения?
Не надо их ничем выводить.
Для пошагового контроля за ходом выполнения программы в Делфи существует встроенный отладчик. Только не говори, что первый раз про него слышишь.
А если все же приспичило выводить, пользуй MessageBox
← →
Сергей М. © (2008-01-21 14:10) [47]
> Ошибка размера
Ошибкой может считаться только LenRes = -1.
Если LenRes = 0, это означает что партнер закрыл соединение по своей иниативе, считать это ошибкой нельзя.
Если 0 < LenRes <= Len, то это не ошибка, а вполне штатная ситуация.
← →
Andrewtitoff © (2008-01-21 14:12) [48]Ясно, так а что делать ели размер несовпал?
Во блин приехали....
Всю жизнь было так:
function MessageBox(Text, Caption: PChar; Flags: Longint): Integer;
а теперь:
int MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)Странно как то... =((((
← →
Andrewtitoff © (2008-01-21 14:20) [49]Ой, эт я опять туплю... =)))
Просто надо писать Application.MessageBox(Text, Caption: PChar; Flags: Longint): Integer;
← →
Andrewtitoff © (2008-01-21 14:25) [50]Не.., с MessageBox виснет так же как и с ShowMessage... =((((
← →
Сергей М. © (2008-01-21 14:31) [51]
> что делать ели размер несовпал?
Повторно вызывать ReceiveBuf, запрашивая оставшиеся данные.
> надо писать Application
Не надо.
> с MessageBox виснет
Отладчик тебе в руки
← →
Andrewtitoff © (2008-01-21 15:05) [52]>Повторно вызывать ReceiveBuf, запрашивая оставшиеся данные.
Так это что ли вычитать из размера файла то что передалось и вызывать ReceiveBuf уже с Buf = FileSize - ReceiveSize ?
← →
Сергей М. © (2008-01-21 15:15) [53]Да.
← →
Andrewtitoff © (2008-01-21 15:33) [54]Ну вот вроде как заработало, тока чет я переменных по моему лишку напихал.... =)))
procedure TMyChat.TcpServer1Accept(Sender: TObject;
ClientSocket: TCustomIpClient);
var
asd:tmemorystream;
len:integer;
LenRes1:integer;
LenRes2:integer;
buf:pointer;
begin
len:=68096;
LenRes1:=Len;
LenRes2:=0;
asd:=TMemoryStream.Create;
GetMem(buf,len);
asd.Position:=0;
Repeat
LenRes1:=ClientSocket.ReceiveBuf(buf^,lenRes1);
asd.WriteBuffer(buf^,lenRes1);
LenRes2:=LenRes2+LenRes1;
if LenRes1 <> len then lenRes1 := len-LenRes2;
Until LenRes2 = len;
asd.SaveToFile("c:\000.doc");
asd.Free;
FreeMem(Buf);
end;
← →
Andrewtitoff © (2008-01-21 15:37) [55]Так а как правилино сделать с :
>Или попытайся обслужить более чем одного клиента одновременно
А как сделать то??, хотя для задачи которая на данный момент передомной стоит мне вполне хватит две пары клиент-сервер, но все таки хотелось бы знать и как сделать с несколькими клиентами... =(((
← →
Andrewtitoff © (2008-01-21 15:50) [56]Просто вообще мне надо что бы моя прога пересылала туда-сюда файлы и что бы можно было управлять ей удаленно.., как это сделать?, я конечно могу сейчас наклепать еще одну связку клиент-сервер и по одной передавать файло, а по другой команды, но я так предполагаю что есть способ лучше
← →
Сергей М. © (2008-01-21 15:55) [57]
> А как сделать то?
Ты еще с работой с одним клиентом не разобрался.
Разберешься досконально с одним - вот тогда перейдем к многим клиентам.
А пока вернемся к делам нашим скорбным: предположим, что ReceiveBuf вернул 0 или -1 ...
← →
Andrewtitoff © (2008-01-21 16:17) [58]Так если ноль - то помоему ничего страшного, он просто стока стока же запросит скока и изначально, или тут что то не так?
← →
Сергей М. © (2008-01-21 16:24) [59]0 - это факт штатного закрытия соединения партнером по его инициативе.
-1 - факт нештатного (аварийного) разрыва соединения (например, уборщица партнера БабКлава выдернула шваброй сетевой шнур из компа или злобные хакеры из Тимбукту перекусили оптоволокно между Бобруйском и СПб)
Ни тот ни другой случай ты не ожидаешь и никак не реагируешь на них.
← →
Andrewtitoff © (2008-01-21 16:33) [60]Так а как надо реагировать то?, ну с -1 - отдельный разговор хотя бы потому что в вычислениях бред пойдет, но а с нулем то что?, веди при LenRes1=0 оно все равно не равно len которая в данном случае равна 68096 и следовательно LenRes2 = 0 + 0, а lenRes1 = 68096 - 0 т.е. тем же самым 68096...
← →
Andrewtitoff © (2008-01-21 16:43) [61]Или там заново надо писать TcpClient1.Active := True;?
← →
Сергей М. © (2008-01-21 16:53) [62]Сам-то как думаешь ?
Или ты отвык (или никогда не умел ?) думать ?
← →
Andrewtitoff © (2008-01-21 18:29) [63]думаю надо, зачем сразу оскорблять то? =))))
← →
Slym © (2008-01-22 04:37) [64]Коротко и ясно...
procedure TForm1.TcpServer1Accept(Sender: TObject;
ClientSocket: TCustomIpClient);
var
Stream:TFileStream;
buf:array[byte] of byte;
len:integer;
begin
Stream:=TFileStream.Create("c:\file_"+FormatDateTime("ddmmyyyy_hhmmss",Now)+".txt", fmCreate);
try
while ClientSocket.Connected do
begin
len:=ClientSocket.ReceiveBuf(buf,SizeOf(buf),0);
if len<=0 then Break;
Stream.WriteBuffer(buf,len);
end;
finally
Stream.Free;
end;
end;
← →
Slym © (2008-01-22 04:39) [65]Сохраняется сразу в файл, концом передачи/файла считается отключение клиента...
если клиента тупо оборвало, всеравно считается концом передачи
← →
Slym © (2008-01-22 05:08) [66]Передача файла с именем и размером...
протокол:
FileName: c:\test.txt
Size:10
<<пустая строка, за которой идут бинарные данные
1234567890
<<Сервер может комментировать свое состояниеprocedure TForm1.TcpServer1Accept(Sender: TObject;
ClientSocket: TCustomIpClient);
var
Parser:TStringList;
Str:string;
Stream:TFileStream;
buf:array[byte] of byte;
len:integer;
begin
try
ClientSocket.Sendln("+OK Hello! File sender pleased to meet you");
Parser:=TStringList.Create;
try
Parser.NameValueSeparator:=":";
while ClientSocket.Connected do
begin
Str:=ClientSocket.Receiveln;
if Str="" then break;
Parser.Add(Str);
end;
if Parser.IndexOfName("FileName")<0 then raise Exception.Create("No filename");
if Parser.IndexOfName("Size")<0 then raise Exception.Create("No file size");
Stream:=TFileStream.Create(Parser.Values["FileName"], fmCreate);
try
Stream.Size:=StrToInt(Parser.Values["Size"]);
ClientSocket.Sendln("+OK You can send file");
Stream.Seek(0, soBeginning);
while ClientSocket.Connected do
begin
len:=ClientSocket.ReceiveBuf(buf,SizeOf(buf),0);
if len<=0 then Break;
len:=min(len,Stream.Size-Stream.Position);
Stream.WriteBuffer(buf,len);
if Stream.Size=Stream.Position then
begin
ClientSocket.Sendln("+OK You file accepted. Disconnect.");
ClientSocket.Disconnect;
end;
end;
finally
Stream.Free;
end;
finally
Parser.Free;
end;
except
on E:Exception do
begin
if ClientSocket.Connected then
ClientSocket.Sendln("-ERR Raised exception with message: "+E.Message)
else
raise;
end;
end;
end;
← →
Сергей М. © (2008-01-22 16:37) [67]
> Slym
Медвежья усуга ?
← →
Andrewtitoff © (2008-01-22 18:51) [68]Нет, спасибо, просто сейчас немного не до этого, проблемки появились, сейчас не до этого... =((((
← →
Slym © (2008-01-23 07:41) [69]Сергей М. © (22.01.08 16:37) [67]
Медвежья усуга ?
"Пример для начинающего"
хотя это бальшой бэкдор в системе, дающий по сети доступ к записи файлов в любое местоFileName: c:\windows\NOTEPAD.EXE
← →
hero (2008-01-26 12:42) [70]
> Andrewtitoff ©
если тебя это еще интересует за небольшую сумму могу скинуть исходник своего трояна мыло оставляй
← →
Сергей М. © (2008-01-26 13:38) [71]
> за небольшую сумму могу скинуть
"Налетай, торопись, покупай живопИсь !" (с)
))
← →
Andrewtitoff © (2008-01-26 15:48) [72]2 Сергей М.
Во - во... =))))
коммерсанты блин..., развелось тут всяких... =))))
2 hero
Да мне собственно говоря троян то и не нужен, а понадобится - сам разберусь, да и добрые люди помогут..., тебе на рынок надо может там купят... =)))
← →
hero (2008-01-27 04:05) [73]))
← →
Andrewtitoff © (2008-01-29 12:02) [74]Удалено модератором
Примечание: СПАМ
Страницы: 1 2 вся ветка
Форум: "Сети";
Текущий архив: 2009.03.29;
Скачать: [xml.tar.bz2];
Память: 0.6 MB
Время: 0.048 c