Synapse TCP/IP client and server

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Re: Synapse TCP/IP client and server

Сообщение Sharfik » 25.05.2023 17:47:41

Автор примера интересный человек. Одним из решений сделал систему сообщений "COMMAND: PARAM1, PARAM2" которая полностью валиться, если в параметре есть запятые. Таким образом приходим к необходимости проверки параметров от инъекций, и экранированию специальных символов. Еще, автор сделал шифрование указанной строки на основании номера порта соединения. Только вот у себя на роутере я могу поменять порты, для улицы будет один порт, а внутри сети переадресация пойдет на другой порт. И соответственно шифрование строки будет неверным. Еще, впервые вижу чтобы серверу надо было говорить какой у него IP.... Если несколько сетевых портов у машины это понятно, но насколько правильная реализация - хз. Не у одного серверного приложения не видел таких настроек.
Когда пытался разобраться сам с Indy, то по примерам делал приложение которое отправляет пакет и сразу ждет с таймаутом ответа тут же. Т.е. команда отправки она же и приемник, а тут отправка и получение разделены. Прием файлов сделан через одну общую папку. Это конечно упрощение, но при пересылки больших файлов потом их придется перекопировать в другое место. А значит - подвисание процесса. Еще хитро сделан пинг.
Интересно сколько проблем будет при попытке пересборки на linux :lol: В целом пример сделан как p2p приложение по большей части для создания на его базе своей клиент-сервера много приходится порезать и переиграть, но зато гарантированно работает.
курим дальше....
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 760
Зарегистрирован: 20.07.2013 01:04:30

Re: Synapse TCP/IP client and server

Сообщение delphius » 25.05.2023 20:54:04

Sharfik писал(а):Автор примера интересный человек

Да и вообще, давно пора завести отдельную тему, где концентрировать "хорошие примеры" и "хорошие практики" в современном free pascal. MVVM, clean architecture и тд...
Есть конечно mormot, там уже все готовое реализовано, бери и пользуйся, но иногда это избыточная нагрузка, иногда привязка к конкретному фреймворка, а иногда просто хочется самому руками разобраться почему это надо делать так, а не иначе, да ещё и с самыми новомодными подходами к проектированию и использованием передовых возможностей компилятора
delphius
постоялец
 
Сообщения: 122
Зарегистрирован: 18.03.2020 13:40:11

Re: Synapse TCP/IP client and server

Сообщение Sharfik » 26.05.2023 02:21:32

Мне кажется не предметно это сложно объяснить будет.
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 760
Зарегистрирован: 20.07.2013 01:04:30

Re: Synapse TCP/IP client and server

Сообщение delphius » 26.05.2023 10:36:04

Sharfik писал(а):Мне кажется не предметно это сложно объяснить будет.

Речь не конкретно про данную конкретную библиотеку, а в целом, хотя, вполне вероятно, где-то на гитхабе лежит отличный, кроссплатформенный, понятный, с подробными комментариями, пример реализации TCP/IP клиента и сервера с помощью Synapse, просто мы об этом не знаем :mrgreen:

Однако, судя по тому, что уже пошла вторая реализация на базе первой, видимо нет)
delphius
постоялец
 
Сообщения: 122
Зарегистрирован: 18.03.2020 13:40:11

Re: Synapse TCP/IP client and server

Сообщение Sharfik » 10.07.2023 06:19:54

Диллема...
каждое подключение это отдельный поток для сервера. У сервера есть один класс "Приложения" который отвечает за запись логов. И вот с последним получилось что то странное. Стал писать процедуру удаления записи из БД.
Подряд идет несколько команд от клиента для блокировка области, подтверждения, удаления... и сервер виснет. Как выяснилось потом виснет, а приложение не отвечает на внешние раздражители. И зависание происходит на месте вызова команды синхронизации с основным потоком. Т.е. до написания процедуры все работало, а сейчас стало подвисать. Значит в идеологии стабильности обработки запросов сервером есть пробел. Вот не пойму, что не так. При том, если выбросить синхронизацию и просто запись логов добавить то проблемы нет. С одним клиентом. Если добавить в while выполнения потока sleep, то зависание уходит, но проблема не решается. По прежнему данные не удаляются.
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 760
Зарегистрирован: 20.07.2013 01:04:30

Re: Synapse TCP/IP client and server

Сообщение alexs » 10.07.2023 09:37:44

Ловишь деадлуки на сервере? Посмотри где пересекаются данные - разведи эти места. Если не получается - тогда формируй очередь. Чтобы удаление тоже было отдельным потоком на основе данные, которые помещены в очередь.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4053
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Synapse TCP/IP client and server

Сообщение Alex2013 » 10.07.2023 09:48:23

Возможно вместо синхронизации нужно "закинуть в очередь"? (через Queue(); )
Alex2013
долгожитель
 
Сообщения: 2923
Зарегистрирован: 03.04.2013 11:59:44

Re: Synapse TCP/IP client and server

Сообщение Sharfik » 10.07.2023 18:00:56

Да вот я и не могу понять что там может пересекаться. Один клиент и все. Сервер БД выполняет все команды, и мой сервер получает подтверждение, должен отправить клиенту DONE и записать строку отправки в лог. И на логе все становится плохо.
Читал вчера про то, что возможно потоки забивают работу программы так, что та не успевает обрабатывать "прилетающие" сообщения. Но смог только визуально оживит сервер, не исправив проблему с логами.
Просто во всех статьях, и базовом варианте у автора запись в логи шла через синхронизацию. Если ставлю синхронизацию, то сервер ждет чего то. Вот и не въеду где. А из потока вызывать процедуру не поточного класса, без синхронизации меня пугает. Хотя с одним клиентом работает.

Возможно вместо синхронизации нужно "закинуть в очередь"? (через Queue(); )

А не на оборот? Вчера читал описание, было написано Queue не ждет окончания выполнения, а Synhr.. ждет.
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 760
Зарегистрирован: 20.07.2013 01:04:30

Re: Synapse TCP/IP client and server

Сообщение Alex2013 » 10.07.2023 19:05:17

Sharfik писал(а):А не на оборот? Вчера читал описание, было написано Queue не ждет окончания выполнения, а Synhr.. ждет.

Так в том и фишка. Queue не останавливает работу потока и работает как обычный код обработки события . ( примерно также как таймер который продолжает тикать и вовремя обработки прерывания по таймеру )
Внутри ( если это нужно ) можно сделать защиту "от повторного вхождения" или счетчик . А если этого не делать вызовы будут обрабатываться последовательно примерно так-же как нажатия клавиш.

Главный плюс Queue в том что его исполнение не тормозит рабочий поток, что может быть важно для синхронизации приема данных из сети. (Основной поток немного притормаживает, но это тоже неточно )
Alex2013
долгожитель
 
Сообщения: 2923
Зарегистрирован: 03.04.2013 11:59:44

Re: Synapse TCP/IP client and server

Сообщение Sharfik » 15.07.2023 03:38:45

Небольшое отступление...
Пока по 5 минут перед сном разбирался с предыдущей проблемой, решил сделать простой тест. Точнее, меня озадачило что в прошлой проблеме почему то в логах не в нужной последовательности ID задач. И решил попросить клиента просто отправить команду записи в лог "Привет 0"..."Привет 5". Какое же счастья узнать, что мне не чудится. И в логах сервера возникли надписи с цифрами 3,4,5, а потом 2,4,5.. ну и в таком духе. А это значит что автор базовой библиотеки не сделал чего то, что позволяет программе циклично отправлять и принимать без проблем команды.
Команда пишется как раз в список задач, и на следующем цикле потока идет отправка. И отправка сопровождается задержкой в 500мс, для чтения у клиента и 500мс у сервера. И вот странно... что же оно не работает.
Тест на +Sleep(1000) показал что все становится круто, если не спамить поток сразу.
Отсюда вопрос:
1) Как вопрос синхронизации по времени реализуют в больших профессиональных приложениях?
2) Как оно сделано в играх типа CS, где нельзя просто подождать. Хотя там наверно пакеты не зависят от предыдущих...
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 760
Зарегистрирован: 20.07.2013 01:04:30

Re: Synapse TCP/IP client and server

Сообщение Sharfik » 17.08.2023 01:22:24

В продолжении темы про сервера и клиенты...

Автор изначального примера реализовал как для клиента на сервере, так и для клиента у пользователя вот такой код. Программа может через три процедуры SendMessage, SendStream, SendFile обмениваться с сервером сообщениями. Процедуры помещают задачу в список, и ниже приведенный код выполняет отправку. Как писал выше, один из багов реализации чтение списка задом наперед. Но это еще не все.
Код: Выделить всё
procedure TClientThread.Execute;
var
  Msg: String;
  MsgTyp: Integer;
  Params: TStringArray;
  Size: Int64;
  MS: TMemoryStream;
  I: Integer;
  FileName: String;
  Path: String;
  List: TList;
  Task: TTask;
  FCurPing: QWord;
begin
  FLastPing := GetTickCount64;
  if FTCPBase.FTCPBaseType = tcpServer then
    BroadcastConnection;
  while not Terminated do
  begin
    if (not FBusy) and (not FNeedToBreak) then
    begin
      FBusy := True;
      try
        List := FTaskList.TaskList.LockList;
        try
          for I := List.Count - 1 downto 0 do
          begin
            if FNeedToBreak then
              Break;
            if ProcessTask(TTask(List[I])) then
            begin
              FLastPing := GetTickCount64;
              Task := TTask(List.Items[I]);
              if Task <> nil then
                FTaskList.DeleteTask(Task);
              List.Delete(I);
            end;
          end;
        finally
          FTaskList.TaskList.UnlockList;
        end;
      finally
        FBusy := False;
      end;
    end;

    if not RecvMessage(500, MsgTyp, Msg, Params) then
    begin
      DoDisconnect;
      Break;
    end;
    case MsgTyp of
      0: begin
           FLastPing := GetTickCount64;
           if not FTCPBase.FIgnoreMessage then
             DoRecv(0, Msg, Params, nil);
         end;
      1: begin
           FLastPing := GetTickCount64;
           Size := StrToInt64Def(Params[Length(Params) - 1], -1);
           if Size > 0 then
           begin
             SetLength(Params, Length(Params) - 1);
             MS := TMemoryStream.Create;
             try
               MS.SetSize(Size);
               MS.Position := 0;
               if RecvStream(MS) then
                 DoRecv(1, Msg, Params, MS);
             finally
               MS.Free;
             end;
           end
         end;
      2: begin
           FLastPing := GetTickCount64;
           Size := StrToInt64Def(Params[Length(Params) - 2], -1);
           FileName := Params[Length(Params) - 1];
           SetLength(Params, Length(Params) - 2);
           if Size > 0 then
           begin
             Path := AddDirSeparator(GetDownloadDir(FTCPBase.FDownloadDirectory));
             if DirectoryExists(Path) then
             begin
               Path := Path + FConnection.FUser  + '_'  + FileName;
               if RecvFile(Path, Size) then
                 DoRecv(2, Msg, Params, nil, Path)
             end
             else
               DoError(rsInvalidDirectory, 0);
           end
           else
             FileCreate(Params[0] + Params[1]);
         end;
    end;
    if (FTCPBase.FTCPBaseType = tcpServer) then
    begin
      FCurPing := GetTickCount64;
      if (FCurPing - FLastPing > PingTimeoutServer) then
      begin
        DoDisconnect;
        Break;
      end;
    end
    else if (FTCPBase.FTCPBaseType = tcpClient) then
    begin
      FCurPing := GetTickCount64;
      if (FCurPing - FLastPing > PingTimeoutClient) then
        FTaskList.AddTask('MESSAGE', 'PING', [], nil, '');
    end;
  end;
  FDisconnected := True;
  while not Terminated do
    Sleep(100);
end;

Программа в принципе работала, и общалась. Но как то медленно. Я понимал что это странно, но не придавал значения. Для мое задачи скорость не главное.. пока не уперся в одну проблему. О ней чуть позже. А вот тормоза живут здесь
Код: Выделить всё
if not RecvMessage(500, MsgTyp, Msg, Params) then

Чтение из сокета происходит каждый цикл с ожиданием 500мс. В принципе логично, но медленно. Кто играл в CS поймет. А если пытаться менять параметры таймингов тут и в прочих частях реализации работоспобность падает в ноль.

Сейчас реализация бегает шустро вот с таким вариантом(код черновой).
1. За один цикл производится отправка только одного сообщения из списка
2. За один цикл производится прием только одного сообщения.
3. За счет ниже приведенных SocketActive, SocketCanRead, SocketCanWrite, ReadBeginDialog проверяется живой ли вообще сокет, и есть ли что то в буфере, в случае записи есть ли место куда писать. Если есть работаем по долгому пути и читаем, пишем с длиииинными таймингами. А если все пусто или занято, то идем мимо до следующего повтора.

Код: Выделить всё
procedure TClientOnServerThread.Execute;
var
  Msg     : String;
  iDebugCicle,
  iBadResult,
  IdleCounter,
  MsgTyp  : Integer;
  Params  : TStringArray;
  Size    : Int64;
  MS      : TMemoryStream;
  iStart,
  I,iWhileCount : Integer;
  FileName      : String;
  Path          : String;
  List          : TList;
  Task          : TTask;
  FLastIdleTick,
  FCurIdleTick,
  FLastTick,
  FCurTick,
  FLastTick2,
  FCurTick2     : QWord;
  DoIdleControl,
  DoPing        : Boolean;
begin
  FCurTick    := GetTickCount64;
  FLastTick   := FCurTick;
  FCurTick2   := 0;
  FLastTick2  := 0;
  FCurIdleTick   := FCurTick;
  FLastIdleTick  := FCurTick;
  DoPing         := False;
  DoIdleControl  :=False;
  iWhileCount    := 100;


  if (FTCPBase.TCPBaseType = tcpServer)and(FTCPBase.ActiveOrConnected) then
    BroadcastConnection(FConnection.FUser);

  while not Terminated do
  begin
    MsgTyp      :=-1;
    Msg         :='';
    Params      :=[];
    IdleCounter :=0;
    FCurTick    :=GetTickCount64;
    iStart      :=0;

    if not SocketActive then
    begin
        DoDisconnect;
        Break;
    end;

    //Write data
    if (not FBusy) and (not NeedToBreak) then
    begin
      FBusy := True;
      try
        List := FTaskList.TaskList.LockList;
        try
          iDebugCicle:=0;
          //Отправка
          if (List.Count>0)and(SocketCanWrite) then
          begin
            i:=0;
            iStart:=SocketActive;
            if iStart=1 then
            begin
               if ProcessTask(TTask(List[I])) then
               begin
                  inc(iDebugCicle);
                  inc(IdleCounter);
                  Task := TTask(List.Items[I]);
                  if Task <> nil then
                     FTaskList.DeleteTask(Task);
                  List.Delete(I);
               end;
            end;
          end;

          if iDebugCicle>1 then
          begin
              DoDebugMessage(format('Sended %d messages',[iDebugCicle]));
          end;
        finally
          FTaskList.TaskList.UnlockList;
        end;

      //Read data
      iDebugCicle:=0;
      i:=ReadBeginDialog;
      if i=1 then
      begin
         if not RecvMessage(TIMEOUT_LCICLE_RECVMESSAGE, MsgTyp, Msg, Params) then
         begin
            i:=-1;
            DoDisconnect;
            Break;
         end;
      end
      else if i=-1 then
      begin
          DoDisconnect;
          Break;
      end;

      if (i=1)and(not FNeedToBreak) then
      begin
        inc(iDebugCicle);
        case MsgTyp of
          0: begin
               if ShortCompareText(Msg,'PING')=0 then
               begin
                  if Length(Params)=1 then
                  begin
                     if ShortCompareText(Params[0],'BEGIN')=0 then
                     begin
                        FTaskList.AddTask('PING', 'PING', ['END'], nil, '');
                     end
                     else if ShortCompareText(Params[0],'END')=0 then
                     begin
                        DoPing         := False;
                        FCurTick2      := FCurTick;
                        Ping           := FCurTick2 - FLastTick2;
                     end;
                  end;
               end
               else begin
                  inc(IdleCounter);
                  DoRecv(0, Msg, Params, nil);
               end;
             end;
          1: begin  //stream
               inc(IdleCounter);
               Size      := StrToInt64Def(Params[Length(Params) - 1], -1);
               if Size > 0 then
               begin
                 SetLength(Params, Length(Params) - 1);
                 MS := TMemoryStream.Create;
                 try
                   MS.SetSize(Size);
                   MS.Position := 0;
                   if RecvStream(MS) then
                     DoRecv(1, Msg, Params, MS);
                 finally
                   MS.Free;
                 end;
               end
             end;
          2: begin  //file
               inc(IdleCounter);
               Size      := StrToInt64Def(Params[Length(Params) - 2], -1);
               FileName  := Params[Length(Params) - 1];
               SetLength(Params, Length(Params) - 2);
               if Size > 0 then
               begin
                 Path := AddDirSeparator(GetDownloadDir(FTCPBase.DownloadDirectory));
                 if DirectoryExists(Path) then
                 begin
                   Path := ConcatPaths([Path,FileName]);
                   if RecvFile(Path, Size) then
                     DoRecv(2, Msg, Params, nil, Path)
                 end
                 else
                   DoWriteErrorLog(rsInvalidDirectory, 0);
               end;
             end;
        end;
      end;

      if iDebugCicle>1 then
      begin
          DoDebugMessage(format('Readed %d messages',[iDebugCicle]));
      end;

      finally
        FBusy := False;
      end;

      if (FTCPBase.TCPBaseType = tcpServer)and (not NeedToBreak) then
      begin
        FCurIdleTick    := FCurTick;
        //Раз в KARINA_PING_PERIODONSERVER программа проверяет свой пинг
        if (Ping > KARINA_PING_DISCONNECT) then
        begin
          DoWriteLog(Format('Disconnect by high ping(Limit %d ms)',[KARINA_PING_DISCONNECT]));
          Sleep(10);
          DoDisconnect;
          Break;
        end
        else if (DoPing)and(FCurTick - FLastTick > KARINA_PING_PERIODONSERVER) then
        begin
          DoPing         := False;
          Ping           := 9999;
          DoWriteLog(Format('Disconnect by very high ping(Limit %d ms)',[KARINA_PING_PERIODONSERVER]));
          Sleep(10);
          DoDisconnect;
          Break;
        end
        else if (FCurTick - FLastTick > KARINA_PING_PERIODONSERVER)and (FTCPBase.ClientActionCount=0) then
        begin
          FLastTick  := FCurTick;
          FLastTick2 := FCurTick;
          DoPing     := True;
          FTaskList.AddTask('PING', 'PING', ['BEGIN'], nil, '');
        end;
      end;

    end;

    Sleep(10);

    dec(iWhileCount);
    if iWhileCount<=0 then
    begin
       iWhileCount:=100;
       Synchronize(@SynchronizeData);
    end;

  end; //цикл

  if (FTCPBase.TCPBaseType = tcpServer)and(FTCPBase.ActiveOrConnected) then
     BroadcastDisconnection(FConnection.FUser);

  DoWriteLog(Format(rsMessageClientEndLogStats,[FLogCounterMessage,FLogCounterError,FLogCounterInternal]));

  FDisconnected := True;
  while not Terminated do
  begin
    Sleep(100);
  end;
end;   


Код: Выделить всё
function TBaseThread.SocketActive: Boolean;
begin
  Result := (FBlockSocket.Socket = INVALID_SOCKET) or (FBlockSocket.CanRead(0) and (FBlockSocket.WaitingData = 0));
  Result := not Result;
end;

function TBaseThread.SocketCanRead: Boolean;
begin
  Result := ((FBlockSocket.Socket <> INVALID_SOCKET) And (FBlockSocket.CanRead(0)));
end;

function TBaseThread.SocketCanWrite: Boolean;
begin
  Result := ((FBlockSocket.Socket <> INVALID_SOCKET) And (FBlockSocket.CanWrite(0)));
end;   

function TBaseThread.ReadBeginDialog(ATimeOut: Integer): integer;
var
  sRead: ShortString;
begin
  Result   := 0;
  if not SocketActive then
  begin
    Result   := -1;
  end
  else if FBlockSocket.WaitingData>0 then
  begin
    Result   := 1;
  end;
end;


Что пока не понимаю....
Все работа по циклу с базовыми функциями отправки, но если я хочу сделать к примеру так

Код: Выделить всё
function TBaseThread.ReadBeginDialog(ATimeOut: Integer): integer;
var
  sRead: ShortString;
begin
  Result   := 0;
  sRead    := '';
  sRead    := FBlockSocket.RecvPacket(ATimeOut);
  if (FBlockSocket.LastError > 0) and (FBlockSocket.LastError <> WSAETIMEDOUT) then
  begin
    Result := -1;
  end
  else begin
    if ShortCompareText(sRead,'BEGIN')=0 then
    begin
       FBlockSocket.SendString('START');
       Result := 1;
    end;
  end;
end;   

т.е. клиент прислал короткое BEGIN, сервер ему отвечает START и тем самым переключается в режим "Я ТЕБЯ ВНИМАТЕЛЬНО СЛУШАЮ", то "BEGIN" о казывается и в последующих функциях чтения данных. Хотя по идее его уже извлекли из буфера и он не должен там сидеть. А функция чтения тупит.. и говорит что команду не знает такую. В исходниках работы есть Purge, но толку ноль от него...

вторая беда в частоте команд. Как я понимаю, мы пишем в сокет, если он пустой, если нет то ждем когда освободится. Но на деле кода который копаю получается что(образно) код

Код: Выделить всё
SendMessage('UPDATE',1,'Поле1','Значение 1');
SendMessage('UPDATE',1,'Поле2','Значение 3');
SendMessage('UPDATE',1,'Поле3','Значение 3');

не полностью доходит, а код

Код: Выделить всё
SendMessage('UPDATE',1,'Поле1','Значение 1');
Sleep(100);
SendMessage('UPDATE',1,'Поле2','Значение 3');
Sleep(100);
SendMessage('UPDATE',1,'Поле3','Значение 3');

Стабилен. (*Теперь по закону подлости я должен сам пойти и случайно увидеть причину этого всего)

Вот из-за непоняток работы буфера сокета и не полюбил Indy когда то.
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 760
Зарегистрирован: 20.07.2013 01:04:30

Re: Synapse TCP/IP client and server

Сообщение delphius » 17.08.2023 14:08:20

Sharfik писал(а):В продолжении темы про сервера и клиенты...

Ещё не смотрел, но есть два вопроса.
1. Вы свой код сейчас на базе первой версии делаеие или на основе доработанной автором второй версии, выложенной в апреле этого года в другой ветке форума со значительными улучшениями и доработками? Если нет, то не смотрели ее?
2. Может имеет смысл на гитхабе с вашим кодом поработать? У меня, по работе, сейчас встала близкая задача, но хотелось бы конечно использовать чистые сокеты, чтобы и кроссплатформенно и без использования сторонних библиотек.
Последний раз редактировалось delphius 21.08.2023 11:02:14, всего редактировалось 1 раз.
delphius
постоялец
 
Сообщения: 122
Зарегистрирован: 18.03.2020 13:40:11

Re: Synapse TCP/IP client and server

Сообщение Sharfik » 18.08.2023 00:42:59

1. Из того уже осталось почти ничего, чисто структура потоков. Второй и искать лень, и первый был очень грязный в плане написания. Большого смысла его смотреть уже нет.
2. Гитхаб идет лесом. Не вижу смысла делиться с кем то вне этого форума.
https://disk.yandex.ru/d/ROYPtJzys0REFg
Для запуска нужно настроить и прочитать содержимое settings.xml. Ну и иметь запущенный FB 3.0 Иначе половина функций работать не будет.
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 760
Зарегистрирован: 20.07.2013 01:04:30

Re: Synapse TCP/IP client and server

Сообщение delphius » 19.08.2023 02:18:32

Sharfik писал(а):В исходниках работы есть Purge, но толку ноль от него...

А если повторно прочитать буфер?
Код: Выделить всё
if ShortCompareText(sRead, 'BEGIN') = 0 then
    begin
      FBlockSocket.SendString('START');
      Result := 1;
      FBlockSocket.RecvPacket(ATimeOut);
    end;


Добавлено спустя 16 часов 24 минуты 2 секунды:
Sharfik писал(а):Одним из решений сделал систему сообщений "COMMAND: PARAM1, PARAM2"

По сути автором примера разработан собственный протокол над стеком TCP/IP, соединение и передача данных между клиентом и сервером осуществляется с помощью блокирующих сокетов, реализованных в synapse.

Насколько увидел в коде, что используются высокоуровневые механизмы synapse без мудрежа, поэтому, если будет необходимость, можно будет просто переписать слой непосредственной передачи и реализовать его через обычные сокеты (модули sockets, ssockets) или еще что-то...

Погружаюсь время от времени, когда есть свободная минутка на код, если что, поправляйте!
delphius
постоялец
 
Сообщения: 122
Зарегистрирован: 18.03.2020 13:40:11

Re: Synapse TCP/IP client and server

Сообщение Sharfik » 20.08.2023 16:10:15

delphius писал(а):А если повторно прочитать буфер?

Не пробовал, будет время посмотрю.

delphius писал(а):По сути автором примера разработан собственный протокол над стеком TCP/IP,

Да, но он это так коряво сделал, что лезть в второй вариант уже смысла нет. Уже все равно перекопал все. А у него начиная с инициализации переменных все на добром слове.

Добавлено спустя 18 минут 51 секунду:
Сейчас меня беспокоит, за неимением опыта, прав ли я делая Sleep(10) в цикле.
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 760
Зарегистрирован: 20.07.2013 01:04:30

Пред.След.

Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 11

Рейтинг@Mail.ru