ANTICHAT.XYZ    VIDEO.ANTICHAT.XYZ    НОВЫЕ СООБЩЕНИЯ    ФОРУМ  
Баннер 1   Баннер 2
Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей. Здесь обсуждаются безопасность, программирование, технологии и многое другое. Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
Вернуться   Форум АНТИЧАТ > Программирование > С/С++, C#, Delphi, .NET, Asm
   
Ответ
 
Опции темы Поиск в этой теме Опции просмотра

Особенности WinSock2
  #1  
Старый 29.10.2009, 02:39
Flenov
Участник форума
Регистрация: 22.11.2008
Сообщений: 142
Провел на форуме:
636446

Репутация: 32
По умолчанию Особенности WinSock2

Вопрос первый:

Как правильней отправлять текст?

Вариант первый (Код на Delphi):
Код:
function SendText(Sock: TSocket; S: String): Integer;
begin
  Result:=Send(Sock, PChar(S)^, Length(S), 0);
end;



Вариант второй (Код на Delphi):
Код:
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;


Вопрос второй:

Правильно ли я перевожу в неблокирующий режим?

Фрагмент кока (код на Delphi):

Код:
var
  Sock: TSocket;
  iMode: Cardinal;
....
begin
....

  Sock:=Socket(AF_INET, SOCK_STREAM, 0);
  if (Sock=INVALID_SOCKET) then Raise Exception.Create('Ошибка создания сокета');
  if (Connect(Sock, @SockAddr, Sizeof(SockAddr))=0) then
  begin
    if NoneBlock then
                     begin
                       iMode:=1;
                       IOCtlSocket(Sock, FIONBIO, iMode);
                     end;
...
 
Ответить с цитированием

  #2  
Старый 29.10.2009, 10:49
slesh
Reservists Of Antichat - Level 6
Регистрация: 05.03.2007
Сообщений: 1,985
Провел на форуме:
3288241

Репутация: 3349


Отправить сообщение для slesh с помощью ICQ
По умолчанию

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

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

Код:
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  
Старый 29.10.2009, 15:46
Chrome~
Постоянный
Регистрация: 13.12.2008
Сообщений: 354
Провел на форуме:
1747641

Репутация: 175
Отправить сообщение для Chrome~ с помощью ICQ
По умолчанию

Цитата:
Сообщение от slesh  
Код:
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;
Отлично, спасибо за код! Я не знал о таком способе, не очень люблю работать с указателями.
 
Ответить с цитированием

  #4  
Старый 29.10.2009, 23:29
Flenov
Участник форума
Регистрация: 22.11.2008
Сообщений: 142
Провел на форуме:
636446

Репутация: 32
По умолчанию

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

Код:
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;
т.е. примерно так должно идти.

Второй вопрос. В принципе правильно.
Принципиально неправильный - из-за нерациональности с памятью?

Проверил твою идею.
Да указатели действительно облегчили жизнь.

ЗЫ походу не BufLen а SendLen и ещё походу BufStart ты тут в конце указатель забыл

Последний раз редактировалось Flenov; 30.10.2009 в 03:09..
 
Ответить с цитированием

  #5  
Старый 30.10.2009, 03:08
Flenov
Участник форума
Регистрация: 22.11.2008
Сообщений: 142
Провел на форуме:
636446

Репутация: 32
По умолчанию

А приёмку я осуществляю верно?

Код:
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;
 
Ответить с цитированием

  #6  
Старый 30.10.2009, 15:01
Chrome~
Постоянный
Регистрация: 13.12.2008
Сообщений: 354
Провел на форуме:
1747641

Репутация: 175
Отправить сообщение для Chrome~ с помощью ICQ
По умолчанию

Код:
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;
Код:
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();
 
Ответить с цитированием

  #7  
Старый 30.10.2009, 22:47
Flenov
Участник форума
Регистрация: 22.11.2008
Сообщений: 142
Провел на форуме:
636446

Репутация: 32
По умолчанию

А приёмку как лучше и быстрее можно выполнить?

Кстати, я тут на днях от нехера делать DownLoader написал на чистых сокетах.
Если я статеечку напишу с исходниками - это кому-то нужно или опять всё будут говорить Flenov, ты хернёй маешься?

Последний раз редактировалось Flenov; 30.10.2009 в 23:09..
 
Ответить с цитированием

  #8  
Старый 31.10.2009, 22:52
Chrome~
Постоянный
Регистрация: 13.12.2008
Сообщений: 354
Провел на форуме:
1747641

Репутация: 175
Отправить сообщение для Chrome~ с помощью ICQ
По умолчанию

Цитата:
Сообщение от Flenov  
А приёмку как лучше и быстрее можно выполнить?

Кстати, я тут на днях от нехера делать DownLoader написал на чистых сокетах.
Если я статеечку напишу с исходниками - это кому-то нужно или опять всё будут говорить Flenov, ты хернёй маешься?
Для новичков будет полезно, особенно если работа с Winsock.
 
Ответить с цитированием
Ответ



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
iPhone 3GS: особенности и отличия нового iPhone AquaKlaster Мировые новости 48 06.10.2009 11:31
Инициализация WinSock2 Flenov С/С++, C#, Delphi, .NET, Asm 3 26.05.2009 05:20
Особенности ценовой политики Radeon HD 4770 tinyM Новости мира "железа" 0 28.04.2009 22:25



Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT.XYZ