Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как отправить/принять через WinSock свыше 1gb? [D6]


Страницы:   1 2

NikNet ©   (2005-08-14 17:06:00) 

У кого есть готовый код?


NikNet   (2005-08-18 17:21:00) [1]

Все сделал!!! Это было проще простого !!!

Спасибо ВСЕМММММММ!!!


atruhin   (2005-08-18 00:20:00) [2]

Могу но не буду. Я привел кусок проекта смотри, читай хелп, будут вопросы спрашивай. Там кое что лишнее, элементарного нет, смотри суть.
procedure TAcceptThread.Execute;
не правильная. заметил сейчас, остаток от пула потоков :))
смотри прием, передачу. ДУМАЙ.


Eraser   (2005-08-17 23:41:00) [3]

NikNet ©   (17.08.05 23:38) [32]

http://rentacoder.com/


NikNet   (2005-08-17 23:38:00) [4]

Erik1 ©   (17.08.05 15:22) [29]
atruhin ©   (17.08.05 22:59) [31]
Спасибо!!!

Если вас не затруднит :) НЕ могли бы помочь сделать
SendLong то есть передача длиных сообщений и RecvLong

Я думаю это не только решит мою проблему но многих других...

:)


atruhin   (2005-08-17 22:59:00) [5]

прмерно так
Сервер - но исходник из другого проекта, поэтому смотри анализируй, делай

procedure TPortMapper.Execute;
var
  i : integer;
  TimeCr : TDateTime;
  IT : TInternalThread;
  FAddr: TSockAddrIn;
begin
   GV^.EndWorkEvent:=CreateEvent(nil,true, false, nil);
   //************************************************ // Слушающий поток
   FListenSocket := socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
   if FListenSocket = INVALID_SOCKET then begin
     MessageClient(msgWSAError, WSAGetLastError);
   end else begin
FAddr.sin_family := PF_INET;
FAddr.sin_addr.s_addr := INADDR_ANY;
FAddr.sin_port := htons(GV^.ListenPort);
bind(FListenSocket, @FAddr, SizeOf(FAddr));
listen(FListenSocket, 100);
AcceptThread := TAcceptThread.Create(FListenSocket, GV);
//************************************************
while not Terminated do begin
       Sleep(10);
     end;
   end;
end;

procedure TAcceptThread.Execute;
 var
   FAddr: TSockAddrIn;
   Len: Integer;
   IntPort : PInternalPort;
 begin
    while not Terminated do begin
        New(IntPort);
        Len:=SizeOf(FAddr);
        IntPort^.Port:=Accept(FListenSocket,FAddr,Len); // Подключился новый клиент
        if IntPort^.Port <> INVALID_SOCKET then begin
           IntPort^.Time := Now;
           try
             GV^.IntPorts.Add(IntPort);
           except
           end;
 end else begin
   Dispose(IntPort);
   exit;
 end;
    end;
end;

procedure TInternalThread.Complete;
 const
   MAX_PACKET_SIZE = 4096*2;
 var
   Hs : array [0..3] of THandle;
   WaitResult : DWord;
   EvCount : integer;
   NetworkEvents:TWSANetworkEvents;

     function DataRead(Sct : TSocket; var Data : TData; var LenData : integer) : integer;
     var
Len : integer;
buff : array [0..MAX_PACKET_SIZE] of char;
     begin
Len := Recv(Sct, buff[0], MAX_PACKET_SIZE, 0);
Result := Len;
if (Len = SOCKET_ERROR)
   then begin MessageClient(msgWSAError, WSAGetLastError); exit; end;
if (LenData = 0)and(Len > 0)
   then if Sct = InternalSocket
    then IsInternalRead(TData(@buff), Len, Len)
    else IsExternalRead(TData(@buff), Len, Len);
if Len > 0 then begin
   ReallocMem(Data, LenData + Len);
   Move(Buff[0], Data[LenData], Len);
   inc(LenData, Len);
   if LenData > BufferSizeOut then MessageClient(msgBufferSizeOut, 0);
   if LenData <> Len
      then if Sct = InternalSocket
       then IsInternalRead(Data, LenData, Len)
       else IsExternalRead(Data, LenData, Len);
end;
if SocketError then Result := -1;
     end;

 begin
   SocketError := false;
   fExternalSocket := INVALID_SOCKET;
   fCurrHost := GV^.RemoteAddr;
   fCurrPort := GV^.RemotePort;
   Redirect := fCurrHost <> '';
   fInternalData := nil;
   fExternalData := nil;
   fInternalLen := 0;
   fExternalLen := 0;
   EvCount := 2;
   fTimeOut := AliveTimeout;
   Hs[0] := GV^.EndWorkEvent;
   Hs[1] := WSACreateEvent;
   Hs[2] := WSA_INVALID_EVENT;
   repeat
     WSAEventSelect(InternalSocket, Hs[1], FD_READ or FD_CLOSE); // ожидаем внутеренний сокет
     if EvCount = 3 then begin
WSAEventSelect(ExternalSocket, Hs[2], FD_READ or FD_CLOSE); // внешний
     end;
     WaitResult := WaitForMultipleObjects(EvCount, @Hs[0], false,  fTimeOut*1000);
     case WaitResult of
  WAIT_FAILED,   // неправильный вызов функции (неверный описатель?)
  WAIT_OBJECT_0 + 0 : break; // Окончание работы
  WAIT_TIMEOUT: begin
    {$ifdef pmdebug}LineInLog('TimeOut - ' + inttostr(NumberThread));{$endif}
    MessageClient(msgRecvTimeout, 0);
    break;
  end;
  WAIT_OBJECT_0 + 1 : begin
     WSAEnumNetworkEvents(InternalSocket, Hs[1], @NetworkEvents);
     if NetworkEvents.lNetworkEvents and FD_Read>0 then
 if NetworkEvents.iErrorCode[FD_Read_Bit]=0 then begin // Пришли данные
   if DataRead(InternalSocket, fInternalData, fInternalLen) < 0 then break;
   if (ExternalSocket <> INVALID_SOCKET)and(Hs[2] = WSA_INVALID_EVENT) then begin
      Hs[2] := WSACreateEvent;
      EvCount := 3;
   end;
 end else break;
     if NetworkEvents.lNetworkEvents and FD_Close>0 then begin
       while DataRead(InternalSocket, fInternalData, fInternalLen) > 0 do ;
       break;
     end; {}
  end;
  WAIT_OBJECT_0 + 2 : begin
    WSAEnumNetworkEvents(ExternalSocket, Hs[2], @NetworkEvents);
    if NetworkEvents.lNetworkEvents and FD_Read>0 then
       if NetworkEvents.iErrorCode[FD_Read_Bit]=0 then begin // Пришли данные
   if DataRead(ExternalSocket, fExternalData, fExternalLen) < 0 then break;
       end else break;
    if NetworkEvents.lNetworkEvents and FD_Close>0 then begin
       while DataRead(ExternalSocket, fExternalData, fExternalLen) > 0 do ;
       break;
    end;
  end;
     end;
   until SocketError;
   EndConnect; // Здесь делаем лог.
   if Hs[1] <> WSA_INVALID_EVENT then WSACloseEvent(Hs[1]);
   if Hs[2] <> WSA_INVALID_EVENT then WSACloseEvent(Hs[2]);
   if ExternalSocket <> INVALID_SOCKET then begin
      shutdown(ExternalSocket, SD_BOTH);
      CloseSocket(ExternalSocket);
      fExternalSocket := INVALID_SOCKET;
   end;
   if InternalSocket <> Invalid_SOCKET then begin
     shutdown(InternalSocket, SD_BOTH);
     CloseSocket(InternalSocket);
     fInternalSocket := Invalid_SOCKET;
   end;
   if fExternalData <> nil then FreeMem(fExternalData);
   if fInternalData <> nil then FreeMem(fInternalData);
   {$ifdef pmdebug} LineInLog('Disconnect - '+IntToStr(NumberThread)); {$endif}
end;

но это кусок из портмаппера т.е. задача другая :) но вызовы процедур и работу с данными можно посмотреть. Писать тебе пример здесь вряд ли кто будет, это денег стоит Что непонятно спроси здесь.


NikNet   (2005-08-17 18:14:00) [6]

Slym ©   (17.08.05 04:53) [28]
Можно вопрос? Сколько байт этот код может отправить клиенту/серверу?


Erik1   (2005-08-17 15:22:00) [7]

Еще можно глануть исходник Indy там только блокирующий режим используется, поэтому код проще.


Slym   (2005-08-17 04:53:00) [8]

Выбрось это... Это писал даже не студент первокурсник, а хуже восмикласник.
тоже самое:
procedure SendSock(Socket: Integer;const Str: string);
var i:integer;
begin
 i:=WinSock.send(Socket,PChar(Str)^,Length(Str),0);
// глупая неправильная рекурсия... Stack overflow не беспокоил?
 if i=0 then SendSock(Socket, Str);
//проще но не менее глупо и неправильно так
 repeat
   i:=WinSock.send(Socket,PChar(Str)^,Length(Str),0);
 until i=0;
end;

function RecvSock(Socket: Integer): string;
var i: Integer;
begin
 SetLength(result,1024);
 i:=Recv(Socket, PChar(result)^,Length(result), 0);
 SetLength(result,i);
end;


NikNet   (2005-08-16 18:32:00) [9]

А это не моё!!! и я не знаю что-то  там вобще...
вот  и  спрашиваю пример... :=


Digitman   (2005-08-16 16:59:00) [10]


> NikNet ©   (16.08.05 16:55) [25]


прокомментируй каждуюстрочку - что и почему ты делаешь в ней ..


NikNet   (2005-08-16 16:55:00) [11]


procedure SendSock(Socket: Integer; Str: string);//sending data
var
  Buffer: Array [1..1024] of Byte;
  i: Integer;
begin
  FillChar(Buffer,SizeOf(Buffer),0);
  if Length(Str)>1000 then Exit;
  for i:=1 to Length(Str) do Buffer[i]:=Ord(Str[i]);
  i:=WinSock.send(Socket, buffer, sizeof(buffer), 0);
  if i=0 then SendSock(Socket, Str);
end;

function RecvSock(Socket: Integer): string;//reading data
var
  Buffer: Array [1..100] of Byte;
  i,RecB: Integer;
  BufStr: String;
begin
  BufStr := '';
  RecB:=Recv(Socket, Buffer, SizeOf(Buffer), 0);
  for i:=1 to RecB do
  BufStr := BufStr + Chr(buffer[i]);
  try Result := BufStr; except Result := ''; end;
end;


Digitman   (2005-08-16 08:24:00) [12]


> передает только 255 байт


приводи свой код


Slym   (2005-08-16 04:52:00) [13]

У тебя сложности с АПИ? Зачем тебе АПИ?
Все программы используют АПИ ОС! Delphi предлагает удобную "упаковочку" этого АПИ. TServerSocket - АПИ в обектно-ориентированном виде.


kami   (2005-08-15 19:14:00) [14]

Уппс... не посмотрел, что сервер должен быть на API...
Но все равно - что мешает посмотреть исходники ServerSocket? & ТАК разжимать данные, которые неизвестно пришли полностью или нет, нельзя. У меня, например, на компьютере "стандартный" размер 8192 b.

немного структурируем код [5] :
procedure sendfile(conserver:TSocket; fn:string);
var f:file;
  buf:array[0..65535]of char;
  fs,cnt:longint;
  numread:integer;
  s:string;
begin
 AssignFile(f,fn);// во-первых, лучше использовать FileStream
 {$I-}
 Reset(f,1);
 {$I+}
 if ioresult0 then
   begin
      //senderror;
      exit;
   end;
 fs:=filesize(f);
 s:='sending?'+IntToStr(fs)+#13;
 send(ConServer,s[1],length(s),0);// размер файла узнать лучше FindFirstом, не будет ошибок при открытом файле
 begin
   closefile(f);
   exit;// а здесь что? передали строку с размером и вышли ?
 end;
 Begin
   closefile(f);
   exit;// и еще раз вышли ?
 end;
 cnt:=0;
 {  setwindowtext(mainwin,'Repeat Start');}
 repeat);// а сюда как попадем? уже 2 раза быд Exit !
   blockread(f,buf,8192,numread);// + f уже 2 раза закрыт !
   send(conserver,buf,numread,0);
   cnt:=cnt+numread;
   if wait_n_receive(conserver) 'n!' then
     begin
       closefile(f);
       exit;
     end;
 until cnt>=fs;
 closefile(f);
end;


kami   (2005-08-15 18:50:00) [15]


> передает только 255 байт

Да вы цё?

Посмотрите ветку http://www.delphimaster.ru/cgi-bin/forum.pl?id=1122136315&n=4
пост [11]

+ если разрешит Verg © - перешлю его пример.


NikNet   (2005-08-15 18:16:00) [16]

#17
Она передает только 255 байт и все!!! По  другому я  не умею :(


Digitman   (2005-08-15 16:43:00) [17]

ты не ответил на вопрос [17]


NikNet   (2005-08-15 16:33:00) [18]

Ну  тогда покажите  пример пожалуйста!!! Между
Клиентом и  Сервером только что бы Сервер был на  API(WinSock)

Прошу вас...


Digitman   (2005-08-15 08:49:00) [19]


> NikNet ©   (15.08.05 03:15) [15]


> SendSock(ConSock,Coompress(’0010Ok’));


надо понимать, процедура SendSock() у тебя данные размером ДО 1Гб передает успешно ? А проблемы возникают лишь при передаче данных размером более чем 1Гб ?


Slym   (2005-08-15 04:48:00) [20]

NikNet ©   (14.08.05 18:02) [5]
Этому коду нельзя работать (если он работает)...
Ошибки:
1. break; continue;
2. Работа с неблокирующим сокетом без "сообщений", а опираясь на задержку ЦИКЛОМ!!! и на таймаут.
3. И как ты сЖЫмаешь? 100% ты используешь сжатие без оглядки на фрагментацию пакетов... От этого у тебя "случайные" сбои распаковки


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо