Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.03.29;
Скачать: CL | DM;

Вниз

Как правильно послать файл через 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;
Скачать: CL | DM;

Наверх




Память: 0.62 MB
Время: 0.032 c
2-1233322044
@!!ex
2009-01-30 16:27
2009.03.29
Как вычленить из строки кусок используя маску?


15-1232174993
Tirael
2009-01-17 09:49
2009.03.29
двухкомпьютерный компьютер


2-1233348637
Тимоха
2009-01-30 23:50
2009.03.29
класс TThread и api


2-1233776507
Ramil
2009-02-04 22:41
2009.03.29
TEdit как калькулятор


2-1233912665
NewBie
2009-02-06 12:31
2009.03.29
Отсылка комбинации клавиш в чужое окно