Как лучше организовать TCP Сервер и Клиент

Вопросы программирования и использования среды Lazarus.

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

Re: Как лучше организовать TCP Сервер и Клиент

Сообщение mig-31 » 16.06.2016 15:48:12

Есть еще сетевая библиотека Lnet.
https://lnet.wordpress.com/

К тому же есть PascalScada, которую можно разширить под ваши требования. MODBUS TCP/RTU уже реализованы. Подключение к базам данных тоже через Zeos. Нехватает только MODBUS TCP сервера.
mig-31
постоялец
 
Сообщения: 224
Зарегистрирован: 14.07.2011 13:46:48

Re: Как лучше организовать TCP Сервер и Клиент

Сообщение Vadim » 16.06.2016 16:32:08

vvvch
В таком случае не заморачивайтесь ресурсами, а лучше заморочтесь вопросом удобства разработки. ;-) Объекты, по сравнению с голыми сокетами, более "человеколюбивы". Поэтому лучше начать с какой-нибудь высокоуровневой библиотеки, типа Synapse, чтобы код был понятен с первого прочтения. Вы так быстрее добъётесь результата.
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Как лучше организовать TCP Сервер и Клиент

Сообщение vvvch » 16.06.2016 17:37:32

mig-31
PascalScada мне не понравилась, по тому и взялся писать своё. (Впрочем это частности, просто моё мнение)
А чем lnen отличается от synapse?
Аватара пользователя
vvvch
постоялец
 
Сообщения: 105
Зарегистрирован: 26.04.2013 11:05:39
Откуда: г.Боровичи, Новг. обл.

Re: Как лучше организовать TCP Сервер и Клиент

Сообщение AlphaBlend » 18.06.2016 13:50:10

lnet попроще будет )
Аватара пользователя
AlphaBlend
постоялец
 
Сообщения: 207
Зарегистрирован: 22.05.2016 10:13:10

Re: Как лучше организовать TCP Сервер и Клиент

Сообщение Linus » 18.02.2017 23:44:34

Здравствуйте! Юзаю socket юнит и не могу понять почему периодически не биндится сокет.

Код: Выделить всё
//существуем пока не  мрет приложение
while (not terminated) do
begin
   Fready:=false;
    //'создаем сокет, слушаем, реагируем'
   SockH:=fpSocket(AF_INET, SOCK_STREAM,0);

   SockAddr.sin_family:=AF_INET;
   SockAddr.sin_port:=htons(22409);
   SockAddr.sin_addr.s_addr:=HostToNet((127 shl 24) or 1); //127.0.0.1

   sizeofSockAdr:=sizeof(SockAddr);

   while (fpBind(SockH,@SockAddr, sizeofSockAdr)=-1) do
   begin
      writeln('Ошибка связывания');
      sleep(2000);
   end;


      writeln('Сервер запущен....');


          if (fpListen(SockH,1)=-1) then
             writeln('Ошибка ожидания ')
          else
          begin
             writeln('Ожидание соединения....');


            SockH:=fpaccept(SockH,@SockAddr, @sizeofSockAdr);
            if SockH=-1 then
               writeln('error in Accept')
            else
            begin
                 //*******************************************************
                 writeln('есть соединение...ok');
                 Fready:=true;

                 setlength(in_buf,512);

                 //получаем вход поток, пока сокет на месте (запроc не привышает 36Байт))
                 while (SockH<>-1) do
                 begin
                      fprecv(SockH,@in_buf[0],512,0);

                      if length(PChar(in_buf))=0 then break;

                      writeln('<<'+PChar(in_buf));
                      //шлем на обработку!
                      proc_in_query(PChar(in_buf));
                      in_buf[0]:=0;
                 end;

                 Fready:=false;

                 writeln('потеряно соединение');
                 writeln('Закрываю сокет! =',CloseSocket(SockH));
                 SockH:=-1;
                 sleep(2000);
          end;
   end;
end; //end while
end;                 
Linus
новенький
 
Сообщения: 47
Зарегистрирован: 11.01.2013 22:01:28

Re: Как лучше организовать TCP Сервер и Клиент

Сообщение MysticCoder » 19.02.2017 04:16:50

Linus писал(а): почему периодически не биндится сокет.


ОС сокет с прошлого запуска не убила, бывает если сокет не закроешь перед завершением программы.
MysticCoder
постоялец
 
Сообщения: 154
Зарегистрирован: 14.09.2013 00:20:28

Re: Как лучше организовать TCP Сервер и Клиент

Сообщение olegy123 » 19.02.2017 11:08:29

опция SO_REUSEADDR
olegy123
долгожитель
 
Сообщения: 1643
Зарегистрирован: 25.02.2016 12:10:20

Re: Как лучше организовать TCP Сервер и Клиент

Сообщение Linus » 21.02.2017 20:26:37

как бы
Код: Выделить всё
CloseSocket(SockH)


Ладно это пол беды, как сделать так чтобы сокет при потери клиента мог принять другого? (данный мною выше код данного не выполняет, хотя это и странно)
Linus
новенький
 
Сообщения: 47
Зарегистрирован: 11.01.2013 22:01:28

Re: Как лучше организовать TCP Сервер и Клиент

Сообщение serbod » 21.02.2017 21:46:25

Рекомендую набор компонентов DataPort (также доступен через OnlinePackageManager) - это простая и удобная обертка над synapse, где есть не только TCP/UDP но и UART, FTDI, LPT. Опрос порта/сокета выполняется в отдельном потоке и не тормозит. А используя базовый абстрактный класс TDataPort в качестве свойства класса, можно подключать к объекту разные порты по выбору.

Если нужно что-то посерьезнее, то у меня есть исходники TCP/UDP сервера, рассчитанного на десятки тысяч подключений (используется lnet) с использованием очередей пакетов. И библиотеки для USB/FTDI/CAN а также для RAS (Dial-up), IP Helper (системные настройки сетевых устройств), GSM modem (AT-команды) , но они заточены под конкретное оборудование. Оттуда можно почерпнуть принципы самонастройки, самодиагностики и самовосстановления после сбоев. Как в аналоговой аппаратуре: нет контакта - не работает, есть контакт - заработало. Или может проще тут рассказать?
Аватара пользователя
serbod
постоялец
 
Сообщения: 449
Зарегистрирован: 16.09.2016 11:03:02
Откуда: Минск

Re: Как лучше организовать TCP Сервер и Клиент

Сообщение Linus » 21.02.2017 22:07:09

Это мне ответ?)

Нет, клиент один и только один - другое приложение. Средства только нативные. (желательно одинаковые как для c++ так и для fpc).
Задача на текущий момент сводится к тому что сервер ждет подключение, если клиент после передачи умирает - забыть про него и ждать и принять его еще раз (возможно ни один раз).
В чем пролема в коде? После смерти клиента закрываю сокет, но вот беда, он обратно не хочет прослушиваться/орендоваться и т.д.
Код: Выделить всё
fpsetsockopt(SockH, SOL_SOCKET, SO_REUSEADDR, @opt, sizeof(opt) ); \0
добавил
Linus
новенький
 
Сообщения: 47
Зарегистрирован: 11.01.2013 22:01:28

Re: Как лучше организовать TCP Сервер и Клиент

Сообщение serbod » 21.02.2017 22:49:22

Для TCP-сервера алгоритм такой (для линукса, в винде в принципе то же самое):
1. создаем сокет, функция socket()
2. привязываем сокет к локальному IP-адресу, функция bind()
3. переводим сокет в пассивный режим приема входящих подключений, функция listen()
4. принимаем входящее подключение, функция accept(), при этом создается новый сокет, похожий на исходящий, только уже подключенный
.. пункт 4 повторяем для каждого входящего подключения
5. закрываем сокет, функция close()

Для UDP достаточно только bind(), а listen() не нужен, он не создает новых сокетов, а общается со всеми через один и тот же.

setsockopt() нужен только для извращений и тонкой настройки, в обычном порядке не нужен.
Аватара пользователя
serbod
постоялец
 
Сообщения: 449
Зарегистрирован: 16.09.2016 11:03:02
Откуда: Минск

Re: Как лучше организовать TCP Сервер и Клиент

Сообщение Linus » 21.02.2017 23:39:05

serbod писал(а):Для TCP-сервера алгоритм такой (для линукса, в винде в принципе то же самое):
4. принимаем входящее подключение, функция accept(), при этом создается новый сокет, похожий на исходящий, только уже подключенный
.. пункт 4 повторяем для каждого входящего подключения


Вот какую забыл важную мелочь, создается новый сокет "клиента"...

Код: Выделить всё
procedure ServerSockThread.Execute;
var
  SockAddr:TInetSockAddr;
  sizeofSockAdr:longint;
  opt:integer;

  in_buf:TSockBuf;
begin
//существуем пока не  мрет приложение
   Fready:=false;
    //'создаем сокет, слушаем, реагируем'
   SockH:=fpSocket(AF_INET, SOCK_STREAM,0);
   opt:=1;
   fpsetsockopt(SockH, SOL_SOCKET, SO_REUSEADDR, @opt, sizeof(opt) );

   SockAddr.sin_family:=AF_INET;
   SockAddr.sin_port:=htons(22409);
   SockAddr.sin_addr.s_addr:=HostToNet((127 shl 24) or 1); //127.0.0.1

   sizeofSockAdr:=sizeof(SockAddr);


   while (fpBind(SockH,@SockAddr, sizeofSockAdr)=-1) do
   begin
      writeln('Ошибка связывания');
      sleep(2000);
   end;


      writeln('Сервер запущен....');


          if (fpListen(SockH,1)=-1) then
             writeln('Ошибка ожидания ')
          else
          begin
             writeln('Ожидание соединения....');


            while (not terminated) do
            begin


                 Client:=fpaccept(SockH,@SockAddr, @sizeofSockAdr);
                 if Client=-1 then
                    writeln('error in Accept')
                 else
                 begin
                      //*******************************************************
                      writeln('есть соединение...ok');
                      Fready:=true;

                      setlength(in_buf,36);

                      //получаем вход поток, пока сокет на месте (запроc не привышает 36Байт))
                      while (Client<>-1) do
                      begin

                           fprecv(Client,@in_buf[0],35,0);

                           if length(PChar(in_buf))=0 then break;

                           writeln('<<'+PChar(in_buf));
                           //шлем на обработку!
                           proc_in_query(PChar(in_buf));
                           fillchar(in_buf[0],36,0);
                      end;

                      Fready:=false;

                      writeln('потеряно соединение');
                      writeln('Закрываю сокет! =',CloseSocket(Client));
                 end;
            end; //end while
    end;
end;


Все работает (для указанных выше задач).
Linus
новенький
 
Сообщения: 47
Зарегистрирован: 11.01.2013 22:01:28

Re: Как лучше организовать TCP Сервер и Клиент

Сообщение son » 06.03.2017 16:51:36

Про MODBUS кстати делал так:
1) ставим драйвера MBX7 (у него можно настроить разные типы подключения)
2) ходим через интерфейс этого драйвера
son
новенький
 
Сообщения: 39
Зарегистрирован: 22.11.2011 11:50:58

Re: Как лучше организовать TCP Сервер и Клиент

Сообщение olegy123 » 06.03.2017 17:22:58

полная реализация протокола MODBUS есть в различных компонентах. Он не сложен.
olegy123
долгожитель
 
Сообщения: 1643
Зарегистрирован: 25.02.2016 12:10:20

Re: Как лучше организовать TCP Сервер и Клиент

Сообщение Linus » 02.04.2017 17:13:58

Дополняю тему вопросом: как установить таймаут на чтение из сокета? (fprecv)
а так же проверить сколько скопилось в буфере отправки.
Linus
новенький
 
Сообщения: 47
Зарегистрирован: 11.01.2013 22:01:28

Пред.

Вернуться в Lazarus

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

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

Рейтинг@Mail.ru