Конференция "Сети" » Как правильно послать файл через TcpServer & TcpClient ? [D7, WinXP]
 
  • Andrewtitoff © (21.01.08 12:40) [40]
    >Теперь разнеси своего клиента и сервера по разным углам Тырнета и попытайся передать файл размером более 8 кб

    Вот блин точно..., Len в ReceiveBuf(buf^,len,0); имеет тип word, а он равен 2 байтам т.е. от 0 до 65535...  =((( , а что что бы послать файл побольше его нужно разбивать, или есть какой нить способ?

    >Или попытайся обслужить более чем одного клиента одновременно
    А как сделать то??, хотя для задачи которая на данный момент передомной стоит мне вполне хватит две пары клиент-сервер, но все таки хотелось бы знать и как сделать с несколькими клиентами...  =(((
  • Сергей М. © (21.01.08 13:12) [41]

    > Len в ReceiveBuf(buf^,len,0); имеет тип word


    Ничего подобного.

    В твоей декларации он integer и в прототипе oн тоже integer, так что верхний предел 2гб.

    Да и не в этом дело.

    А дело в том, что результат выполнения ReceiveBuf вовсе не обязан быть равным значению Len - он может быть и меньшим чем Len, вплоть до 0 или -1. Ты этот факт в своем коде никак не учитываешь, потому и грабли тебе обеспечены. Я же сказал тебе - анализируй результат !
  • Сергей М. © (21.01.08 13:14) [42]

    > Canvas does not allow drawing


    Убирай ShowMessage.
  • Andrewtitoff © (21.01.08 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 © (21.01.08 13:55) [44]
    Опять ShowMessage?, а почему, при чем тут оно?, и чем можно тогда выводить сообщения?
  • Сергей М. © (21.01.08 13:58) [45]
    Ты по-русски читать умеешь ?

    Сказано же - убирай к чертовой бабушке все свои ShowMessage !)

    Нельзя в доп.потоке обращаться  визуальным VCL-контролам !
  • Сергей М. © (21.01.08 14:00) [46]

    > чем можно тогда выводить сообщения?


    Не надо их ничем выводить.
    Для пошагового контроля за ходом выполнения программы в Делфи существует встроенный отладчик. Только не говори, что первый раз про него слышишь.
    А если все же приспичило выводить, пользуй MessageBox
  • Сергей М. © (21.01.08 14:10) [47]

    > Ошибка размера


    Ошибкой может считаться только LenRes = -1.

    Если LenRes = 0, это означает что партнер закрыл соединение по своей иниативе, считать это ошибкой нельзя.

    Если 0 < LenRes <= Len, то это не ошибка, а вполне штатная ситуация.
  • Andrewtitoff © (21.01.08 14:12) [48]
    Ясно, так а что делать ели размер несовпал?

    Во блин приехали....

    Всю жизнь было так:
    function MessageBox(Text, Caption: PChar; Flags: Longint): Integer;
    а теперь:
    int MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)Странно как то... =((((
  • Andrewtitoff © (21.01.08 14:20) [49]
    Ой, эт я опять туплю... =)))
    Просто надо писать Application.MessageBox(Text, Caption: PChar; Flags: Longint): Integer;
  • Andrewtitoff © (21.01.08 14:25) [50]
    Не.., с MessageBox виснет так же как и с ShowMessage...  =((((
  • Сергей М. © (21.01.08 14:31) [51]

    > что делать ели размер несовпал?


    Повторно вызывать ReceiveBuf, запрашивая оставшиеся данные.


    > надо писать Application


    Не надо.


    > с MessageBox виснет


    Отладчик тебе в руки
  • Andrewtitoff © (21.01.08 15:05) [52]
    >Повторно вызывать ReceiveBuf, запрашивая оставшиеся данные.

    Так это что ли вычитать из размера файла то что передалось и вызывать ReceiveBuf уже с Buf = FileSize - ReceiveSize ?
  • Сергей М. © (21.01.08 15:15) [53]
    Да.
  • Andrewtitoff © (21.01.08 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 © (21.01.08 15:37) [55]
    Так а как правилино сделать  с :

    >Или попытайся обслужить более чем одного клиента одновременно

    А как сделать то??, хотя для задачи которая на данный момент передомной стоит мне вполне хватит две пары клиент-сервер, но все таки хотелось бы знать и как сделать с несколькими клиентами...  =(((
  • Andrewtitoff © (21.01.08 15:50) [56]
    Просто вообще мне надо что бы моя прога пересылала туда-сюда файлы и что бы можно было управлять ей удаленно.., как это сделать?, я конечно могу сейчас наклепать еще одну связку клиент-сервер и по одной передавать файло, а по другой команды, но я так предполагаю что есть способ лучше
  • Сергей М. © (21.01.08 15:55) [57]

    > А как сделать то?


    Ты еще с работой с одним клиентом не разобрался.

    Разберешься досконально с одним - вот тогда перейдем к многим клиентам.

    А пока вернемся к делам нашим скорбным: предположим, что ReceiveBuf вернул 0 или -1 ...
  • Andrewtitoff © (21.01.08 16:17) [58]
    Так если ноль - то помоему ничего страшного, он просто стока стока же запросит скока и изначально, или тут что то не так?
  • Сергей М. © (21.01.08 16:24) [59]
    0 - это факт штатного закрытия соединения партнером по его инициативе.
    -1 - факт нештатного (аварийного) разрыва соединения (например, уборщица партнера БабКлава выдернула шваброй сетевой шнур из компа или злобные хакеры из Тимбукту перекусили оптоволокно между Бобруйском и СПб)

    Ни тот ни другой случай ты не ожидаешь и никак не реагируешь на них.
 
Конференция "Сети" » Как правильно послать файл через TcpServer & TcpClient ? [D7, WinXP]
Есть новые Нет новых   [134431   +14][b:0][p:0.001]