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

Вниз

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

Наверх




Память: 0.58 MB
Время: 0.028 c
14-1130844262
Juice
2005-11-01 14:24
2005.11.27
Devexpress Quantum Grid


5-1113565924
имя
2005-04-15 15:52
2005.11.27
Внимание Подлог!!!


2-1131599978
paule
2005-11-10 08:19
2005.11.27
Перенос строки в Memo


2-1131531155
Al_Ba
2005-11-09 13:12
2005.11.27
Помогите ПЛЗ..........


2-1131284903
Mouse_Rat
2005-11-06 16:48
2005.11.27
Как узнать путь к файлу?