TSocketClient

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

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

Ответить
amandra
незнакомец
Сообщения: 2
Зарегистрирован: 16.12.2008 11:14:01

TSocketClient

Сообщение amandra »

необходимо написать софтину под WinCE
железка - промышленная панель, advantech ppc-l60 с WinCE 4.2 net
задача проста - опрос контроллера по протоколу modbus tcp, в дельфе пятой попробовал - все нормально
стоит Lazarus-0.9.26.1-17845-fpc-2.2.2-20081216-cross-arm-wince-win32.exe
в стандарной поставке компонентов для сети нет, пытаюсь установить TSocketClient
при компиляции выдает ошибку, что ему каких-то файлов не хватает - ищу их и прописываю в параметрах компилятора в разделе Пути, в поле "другие модули..." пути до этих файлов
тут дошел до файла systemh.inc, он находиться в C:\lazarus\fpc\2.2.2\source\rtl\inc
путь до него прописал, но все равно

Код: Выделить всё

C:\lazarus\fpc\2.2.2\source\rtl\wince\system.pp(31,2) Fatal: Can't open include file "systemh.inc"

в чем может быть проблема?
Mr.Smart
долгожитель
Сообщения: 1796
Зарегистрирован: 29.03.2008 00:01:11
Откуда: из леса!

Сообщение Mr.Smart »

Простейшая программа (одна форма) компилируется?
Посоветую посмотреть в сторону synasnap там есть простейшие примитивы для работы с сокетами хотя я лично под ВинЦЕ не разу ещё не использовал сокеты.
amandra
незнакомец
Сообщения: 2
Зарегистрирован: 16.12.2008 11:14:01

Сообщение amandra »

простейший проект компилиться
Аватара пользователя
andreymal
незнакомец
Сообщения: 5
Зарегистрирован: 22.10.2011 23:41:29
Контактная информация:

Сообщение andreymal »

Где этот TSocketClient вообще можно взять? Все ссылки на официальной вики битые.
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

andreymal
А Вам именно TSocketClient нужен? В packages\fcl-base\examples есть примеры dsockcli.pp и dsocksvr.pp с примерами сокетных клиента и сервера.
Аватара пользователя
andreymal
незнакомец
Сообщения: 5
Зарегистрирован: 22.10.2011 23:41:29
Контактная информация:

Сообщение andreymal »

Вообще мне нужен хоть какой-нибудь сокет. :)
Последний раз редактировалось andreymal 07.01.2012 19:11:49, всего редактировалось 1 раз.
Bupyc
постоялец
Сообщения: 137
Зарегистрирован: 29.08.2007 18:22:42

Сообщение Bupyc »

andreymal писал(а):Вообще мне нужен хоть какой-нибудь сокет. :)


Если хоть какой-нибудь, то чем Вас модуль Sockets не устраивает?
Доступен без всяких дополнительных компонент + точно работает под WinCE (сам проверял).
Аватара пользователя
andreymal
незнакомец
Сообщения: 5
Зарегистрирован: 22.10.2011 23:41:29
Контактная информация:

Сообщение andreymal »

Bupyc писал(а):чем Вас модуль Sockets не устраивает?

Тем, что документацию не нашёл, а по одному нагугленному примеру ниасилил.
Bupyc
постоялец
Сообщения: 137
Зарегистрирован: 29.08.2007 18:22:42

Сообщение Bupyc »

Что нужно сделать? Поделюсь примером.
Аватара пользователя
andreymal
незнакомец
Сообщения: 5
Зарегистрирован: 22.10.2011 23:41:29
Контактная информация:

Сообщение andreymal »

Нужно сокеты, клиент и сервер :) Я ещё не придумал, что конкретно с ними делать, освоить сперва надо.

Добавлено спустя 3 минуты 55 секунд:
dsockcli.pp похоже для юникса, не компилится на винде, а я кроссплатформенно хочу.
Bupyc
постоялец
Сообщения: 137
Зарегистрирован: 29.08.2007 18:22:42

Сообщение Bupyc »

Ок, чуть попозже (сегодня вечером) пример скину. Сейчас нет под рукой старого кода. В принципе, и клиент и сервер (в том числе на Linux и WinCE) я поднимал.

Добавлено спустя 25 минут 17 секунд:
Вот, ссылка на один из моих старых постов:
http://www.freepascal.ru/forum/viewtopic.php?f=5&t=3070

Я там по теме TCP клиента отписывался. Код, приведенный в самом нижнем посте, без проблем компилился и работал в дельфях под Win и в FPC под WinCE.

Чуть позже поделюсь как поднять сервер.
Кстати, по поводу сервера. Какая ось интересует в большей степени?
Почему интересуюсь - у меня есть две реализации сервера: с многопоточной обработкой входящих данных (работает под Win, WinCE, Linux) и однопоточной (только Win). Вторая, по опыту работы, более оптимальна, т.к. с ней легче избегать разного рода deadlock'ов, хотя и хуже в плане кроссплатформенности. В общем, какой вариант сервера более интересен?
Аватара пользователя
andreymal
незнакомец
Сообщения: 5
Зарегистрирован: 22.10.2011 23:41:29
Контактная информация:

Сообщение andreymal »

Который кроссплатформенный.
Bupyc
постоялец
Сообщения: 137
Зарегистрирован: 29.08.2007 18:22:42

Сообщение Bupyc »

С сервером немного сложнее. Требуются определённые навыки в написании мультипоточных приложений.
Кроме того, тот класс которым я пользуюсь, содержит код, специфичный для моего приложения и
сходу разобраться в нём будет достаточно тяжело.

Поэтому не смогу дать конечную реализацию, просто приведу здесь куски кода, которые в конечном итоге
реализуют функционал TCP сервера.

Итак, по шагам:

0. В uses прописываем примерно следующее:

Код: Выделить всё

uses
 {$IFNDEF UNIX}
 WinSock,
 Windows,
 {$ELSE}
 Sockets;
 {$ENDIF}


1. Инициализируем WinSock (нужно для Win и WinCE, не нужно для Linux)

Код: Выделить всё

WSAStartup(MakeWord(2,0),Data);


2. Создаем отдельный поток, в котором запускаем примерно такой код:

Код: Выделить всё

 var
  newSocket : TSocket;
  serv      : sockaddr_in;
  addr_len     : Integer;
  addr         : sockaddr_in;

 .......................................................................

 newSocket := socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

  if (newSocket <> INVALID_SOCKET) then
  begin
   serv.sin_family      := AF_INET;
   serv.sin_port        := htons(Port);                    // <-- TCP порт, который мы слушаем
   serv.sin_addr.S_addr := INADDR_ANY;

   if (bind(newSocket,serv,SizeOf(sockaddr_in)) = {$IFNDEF UNIX} SOCKET_ERROR {$ELSE} False {$ENDIF}) then
   begin
    closesocket(newSocket);
    newSocket := INVALID_SOCKET;
   end;

   if (newSocket <> INVALID_SOCKET) then
   begin
    if (listen(newSocket,SOMAXCONN) = {$IFNDEF UNIX} SOCKET_ERROR {$ELSE} False {$ENDIF}) then
    begin
     closesocket(newSocket);
     newSocket := INVALID_SOCKET;
    end;

    // Цикл приема подключений
   repeat
    addr_len := SizeOf(sockaddr_in);

    try
     clientSocket := accept(newSocket ,{$IFNDEF UNIX}@{$ENDIF}Addr,{$IFNDEF FPC}@{$ENDIF}Addr_len);
    except
     clientSocket := INVALID_SOCKET;
    end;

    if (clientSocket <> INVALID_SOCKET) then
    begin
     // Здесь мы приняли подключение.
     // Нужно создать новый поток, который будет взаимодействовать с клиентом и передать ему значение clientSocket


    end;
   until ((clientSocket = INVALID_SOCKET) or Thread.Terminated);
   end;
  end;


3. В клиентском потоке запускаем цикл приёма и обработки данных:

Код: Выделить всё

 const
  cnStaticBufferSize = 4096;

 var
  clientSocket : TSocket;
  staticBuf    : array [0 .. cnStaticBufferSize - 1] of Char;
  nRet         : Integer;

.......................................................................................

  repeat
   nRet := recv(clientSocket,staticBuf[0],cnStaticBufferSize,0);

   if (nRet > 0) then
   begin
    // staticBuf содержит nRet байт пришедших данных
    // Можно их обработать


   end;
  until ((nRet <= 0) or Thread.Terminated);



4. При завершении работы приложения не забываем про WSACleanUp (если мы под Win,WinCE).

В принципе, все. Хотя, мог упустить какие-то мелочи.

Хотел бы еще заметить, что в приведенном коде используются прямые обращения к сетевым функциям. Если не ошибаюсь, в fpc есть соответствующие аналоги с префиксом fp (например, fpsocket, fpbind и т.д.), которые по сути являются обертками. Цель их присутствия в rtl фрипаскаля мне до конца не ясна. Возможно, с их помощью можно было написать приведенный код более лаконично (например, без лишних директив IFDEF).
Я намеренно не стал использовать обёртки из rtl fpc, т.к. основной средой разработки для меня является Delphi. Там эти обёртки отсутсвуют.
Ответить