Особенности WinSock2

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Flenov, 29 Oct 2009.

  1. Flenov

    Flenov Member

    Joined:
    22 Nov 2008
    Messages:
    20
    Likes Received:
    17
    Reputations:
    0
    deleted
     
    #1 Flenov, 29 Oct 2009
    Last edited: 28 Jan 2015
    1 person likes this.
  2. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    Вопрос 1:
    Вариант Result:=Send(Sock, PChar(S)^, Length(S), 0); приемлем для строк относительно не большого размера. Чтобы люде не говорили, что данные не смогт сразу послаться итд итп. но это уже более низкий уровень будет думать. А от тебя данные уйдут в ядро и вернется значение сколько данных послан. Именно послано, а не дошло.

    Второй вариант - принципиально не правильный. Зачем копировать данные во временный буфер? Юзай указатели. т.е. это можно оформить примерно так:

    Code:
    function SendText(Sock: TSocket; S: String): Integer;
    var
      SendLen: Integer;
      BufStart : pchar;
      BufLen : integer;
    begin
      BufLen := Length(s); // сразу вычислим размер, чтобы потом постоянно не считать
      BufStart := @s[1]; // установим указатель на начало строки
    
      While ( BufLen > 0) do // если есть что отправлять
      begin
        if BufLen < 1024 then SendLen := BufLen else BufLen := 1024; // вычислим сколько байт отправлять. Но не более 1024 (1024- это так к примеру) 
    
        SendLen := Send(Sock, BufStart, SendLen, 0); // отправим
        if SendLen <= 0 then break; // если ошибка была то выйти из цикла отправки
        BufStart := pchar(dword(BufStart) + SendLen); // переместим указатель дальше
        BufLen := BufLen - SendLen; // уменьшим кол-во оставшихся данных 
      end;
    end;
    
    т.е. примерно так должно идти.

    Второй вопрос. В принципе правильно.
     
  3. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    936
    Likes Received:
    162
    Reputations:
    27
    Отлично, спасибо за код! Я не знал о таком способе, не очень люблю работать с указателями.
     
  4. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    936
    Likes Received:
    162
    Reputations:
    27
    Code:
    function SendText(Sock: TSocket; S: String): Integer;
    var
      MainBuff: Array[0..1023] of Char;
      iSize: Integer;
    begin
      Result:=0;
      While (Length(S)>0) do
                            begin
                              iSize:=Length(S);
                              if (iSize>SizeOf(MainBuff)) then iSize:=SizeOf(MainBuff);
                              FillChar(MainBuff, SizeOf(MainBuff), 0);
                              CopyMemory(@MainBuff, PChar(S), iSize);
                              Delete(S, 1, iSize);
                              Result:=Result+Send(Sock, MainBuff, iSize, 0);
                            end;
    end;
    Code:
    function ReceiveText(Sock: TSocket; var S: String): Integer;
    var
      MainBuff: Array[0..1023] of Char;
      iSize: Integer;
    begin
      Result:=0;
      While True do
                   begin
                     FillChar(MainBuff, SizeOf(MainBuff), 0);
                     iSize:=Recv(Sock, MainBuff, SizeOf(MainBuff), 0);
                     if (iSize<1) then Break;
                     S:=S+String(MainBuff);
                     Result:=Result+iSize;
                   end;
    end;
    Оба твои коды правильные. Они не слишком хороши в реализации. Также, долго могут выполняться следующие процедуры: FillChar(); CopyMemory();
     
  5. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    936
    Likes Received:
    162
    Reputations:
    27
    Для новичков будет полезно, особенно если работа с Winsock.