Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2005.11.27;
Скачать: [xml.tar.bz2];

Вниз

Как отправить/принять через WinSock свыше 1gb?   Найти похожие ветки 

 
NikNet ©   (2005-08-14 17:06) [0]

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


 
забыл [кто-то зарегил мой ник]   (2005-08-14 17:10) [1]

а в чем сложности, милейший? ))))


 
tesseract ©   (2005-08-14 17:15) [2]

нареж кусками поменьше да и посылай


 
panov ©   (2005-08-14 17:31) [3]

http://www.delphimaster.ru/cgi-bin/forum.pl?n=4&search=WinSock


 
NikNet ©   (2005-08-14 17:41) [4]

Да мне бы типа SendLong и  RecvLong!

Просто я много  всякой ерунды наделал в проге
а все заново лень даи ещё вдруг что-то не так
сделаешь и все потом думаю  что там не так :(

А код примерно у меня такой
     0003 : Beep(Param);
     0006 : ChatEnd(Param);
     0007 : ChatID(Param);
     ...

и лист кода весит около 28kb вот и не охото все менять...


 
NikNet ©   (2005-08-14 18:02) [5]

Вот вобщем нашол но не фига непонил 8(

function wait_n_receive(ConServer:TSocket):string;
 var
   str,res:shortstring;
   tmp:cardinal;
   bsiz:Cardinal;
label z;
begin
 str:="";
 res:="";
 tmp:=gettickcount;
 repeat
 z: bsiz:=recv(conserver,str[1],255,0);
   if bsiz=-1 then
   begin
      bsiz:=wsagetlasterror;
      if bsiz=WSAEWOULDBLOCK then
      begin
       res:="e!"#13;
       break;
       continue;
      end else  break;
end;
   setlength(str,bsiz);
   res:=res+str;
   if not connected then break;
   if tmp+40000 <= gettickcount then break;
   if res="" then goto z;
 until res[length(res)]=#13;
 setlength(res,length(res)-1);
 result:=res;
end;
(*
function wait_n_recvbuf(var b; siz:integer):integer;
var s:integer;
   tmp:cardinal;
begin
 s:=0;
 tmp:=gettickcount;
 repeat
   bsiz:=recv(conserver,pointer(longint(@b)+s)^,siz,0);
   if bsiz=-1 then begin
     bsiz:=wsagetlasterror;
     if bsiz<>WSAEWOULDBLOCK then break;
     continue;
   end;
   if not connected then begin result:=0; exit; end;
   if tmp+60000<=gettickcount then break;
   s:=s+bsiz;
 until s=siz;
 result:=s;
end;

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);
 {$I-}
 Reset(f,1);
 {$I+}
 if ioresult<>0 then
 begin
 //senderror;
 exit;
 end;
 fs:=filesize(f);
 s:="sending?"+IntToStr(fs)+#13;
 send(ConServer,s[1],length(s),0);
 begin closefile(f); exit; end;
 Begin
   closefile(f);
   exit;
 end;
 cnt:=0;
{  setwindowtext(mainwin,"Repeat Start");}
 repeat
   blockread(f,buf,8192,numread);
   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;


 
NikNet ©   (2005-08-14 18:03) [6]

Кстати данные сжымаются так что всякие оконцовки не пройдут  :(


 
atruhin ©   (2005-08-14 19:03) [7]

За такой код поубивавбы! Сотри его и не вздумай смотреть! В чем проблема то? Какая разница отправить 100 байт или 100 гб? При правильно написаном алгоритме ни какой. Чтобы помочь с кодом, скажи хоть что используешь, кмпоненты, winsock ...


 
NikNet ©   (2005-08-14 19:24) [8]

Да вот не могу  отправить свыше одного гига  карочи надо сделать две
процедуры и  ф-ций  которые бы  принимали,/отправляли данные
и все это  для  WinSock!

Client использует TClientSocket
А Сервер на чистом API(WinSock)

Сервер должен передать данные (НЕ ФАЙЛ) размером 1gb
А Клиент должен принять их и выводить на экран или файл.

В общем, оптимизацию я предусмотрел! Так  есть один алгоритм
быстрой передачи  данных…  Как с этим поконьчу скину.

Вот, в общем, то проблема как  это реализовать.


 
забыл [кто-то зарегил мой ник]   (2005-08-14 19:44) [9]

я не вижу проблемы. какая разница сколько передавать инфы? что именно передается то?


 
забыл [кто-то зарегил мой ник]   (2005-08-14 20:46) [10]

А почему не реализовал клиент и сервер единообразно?


 
NikNet ©   (2005-08-15 00:19) [11]

#9
Передаётся огромный зашифрованый/сжатый блок
который оптимизированый!!! ЕСТЬ СИМВОЛЫ КОТОРЫЕ
Сокеты передают очень быстро!!!  

Вот этот блок и надо по кусочкам передать
через WinSock!

#10
А на клиенте есть кучу наворотов!!!


 
NikNet ©   (2005-08-15 00:33) [12]

Люди хлтя бы покажите вобще как эти данные(свыше 1mb) передавать?


 
Alexander Panov ©   (2005-08-15 01:41) [13]

NikNet ©   (15.08.05 0:33) [12]

Точно так же, как и меньше мегабайта.


 
NikNet ©   (2005-08-15 02:01) [14]

Alexander Panov ©   (15.08.05 01:41) [13]
Точно так же, как и меньше мегабайта.


а как? покажите пример?
Между WinSock - SERVER и ClientSocket1 - Client?
Плизззз кому не составит труда...


 
NikNet ©   (2005-08-15 03:15) [15]

В  общем, у меня между сервером и клиентом передача идет таким образом:

SERVER:

    Case NumCmd of
       0010 :  //  Вывести сообщение от администратора
        Begin
          MessageBox(hWnd,’Администратор запретил использовать эти ф-ций!’);
          SendSock(ConSock,Coompress(’0010Ok’));
        End;
    end;


CLIENT:
    Data   := Uncompress(RecvData);       //Uncompress(RecvData)  =  0010Ok
    NumCmd := StrToInt(copy(Data,1,4));  
    Param  := Copy(Data,5,Length(Data)-4);
     Case NumCmd of
         0010:
           Begin
                IF Param =’Ok’ Then
               ShowMessage(‘Сообщение было отправлено’);
           End;
     end;
    Caption:=IntToStr(NumCmd)+"-"+IntToStr(Length(Param));


 
Slym ©   (2005-08-15 04:48) [16]

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


 
Digitman ©   (2005-08-15 08:49) [17]


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


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


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


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

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

Прошу вас...


 
Digitman ©   (2005-08-15 16:43) [19]

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


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

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


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


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

Да вы цё?

Посмотрите ветку http://delphimaster.net/view/6-1122136315/
пост [11]

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


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

Уппс... не посмотрел, что сервер должен быть на 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 ioresult<>0 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;


 
Slym ©   (2005-08-16 04:52) [23]

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


 
Digitman ©   (2005-08-16 08:24) [24]


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


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


 
NikNet ©   (2005-08-16 16:55) [25]


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 16:59) [26]


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


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


 
NikNet ©   (2005-08-16 18:32) [27]

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


 
Slym ©   (2005-08-17 04:53) [28]

Выбрось это... Это писал даже не студент первокурсник, а хуже восмикласник.
тоже самое:
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;


 
Erik1 ©   (2005-08-17 15:22) [29]

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


 
NikNet ©   (2005-08-17 18:14) [30]

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


 
atruhin ©   (2005-08-17 22:59) [31]

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

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 23:38) [32]

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

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

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

:)


 
Eraser ©   (2005-08-17 23:41) [33]

NikNet ©   (17.08.05 23:38) [32]

http://rentacoder.com/


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

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


 
NikNet ©   (2005-08-18 17:21) [35]

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

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



Страницы: 1 вся ветка

Форум: "Сети";
Текущий архив: 2005.11.27;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.58 MB
Время: 0.015 c
14-1130886861
Ораклиный глаз
2005-11-02 02:14
2005.11.27
Алькаида готовит диверсию?


2-1131628633
Piero
2005-11-10 16:17
2005.11.27
Получить Handle запускаемого процесса


6-1124186136
AMB
2005-08-16 13:55
2005.11.27
Почта из Delphi


2-1131106411
12next
2005-11-04 15:13
2005.11.27
Заменить процедуру события OnClick


4-1127470851
Новый
2005-09-23 14:20
2005.11.27
Zip в Xp! Где он! Как с ним работать?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский