C ++ TCP Socket Plugin - PullRequest
       10

C ++ TCP Socket Plugin

0 голосов
/ 11 мая 2011

В настоящее время я работаю с имитатором VBS2 и пытаюсь написать плагин для сокета TCP.У меня есть клиентское приложение, которое я хочу подключить к плагину и отправить одно сообщение.Возможно, это будет иметь больше смысла, если я опубликую существующий код плагина:

#include <windows.h>
#include "VBSPlugin.h"

// Command function declaration
typedef int (WINAPI * ExecuteCommandType)(const char *command, char *result, int resultLength);

// Command function definition
ExecuteCommandType ExecuteCommand = NULL;

// Function that will register the ExecuteCommand function of the engine
VBSPLUGIN_EXPORT void WINAPI RegisterCommandFnc(void *executeCommandFnc)
{
  ExecuteCommand = (ExecuteCommandType)executeCommandFnc;
}

// This function will be executed every simulation step (every frame) and took a part     in the simulation procedure.
// We can be sure in this function the ExecuteCommand registering was already done.
// deltaT is time in seconds since the last simulation step
VBSPLUGIN_EXPORT void WINAPI OnSimulationStep(float deltaT)
{
  //{ Sample code:
ExecuteCommand("0 setOvercast 1", NULL, 0);
  //!}
}

// This function will be executed every time the script in the engine calls the script function "pluginFunction"
// We can be sure in this function the ExecuteCommand registering was already done.
// Note that the plugin takes responsibility for allocating and deleting the returned string
VBSPLUGIN_EXPORT const char* WINAPI PluginFunction(const char *input)
{
  //{ Sample code:
  static const char result[]="[1.0, 3.75]";
  return result;
  //!}
}

// DllMain
BOOL WINAPI DllMain(HINSTANCE hDll, DWORD fdwReason, LPVOID lpvReserved)
{
   switch(fdwReason)
   {
      case DLL_PROCESS_ATTACH:
         OutputDebugString("Called DllMain with DLL_PROCESS_ATTACH\n");
         break;
      case DLL_PROCESS_DETACH:
         OutputDebugString("Called DllMain with DLL_PROCESS_DETACH\n");
     break;
      case DLL_THREAD_ATTACH:
         OutputDebugString("Called DllMain with DLL_THREAD_ATTACH\n");
         break;
      case DLL_THREAD_DETACH:
         OutputDebugString("Called DllMain with DLL_THREAD_DETACH\n");
         break;
   }
   return TRUE;
}

Сообщение, отправленное плагину, будет использоваться в функции OnSimulationStep () путем передачи в качестве аргумента в ExecuteCommand ().Тем не менее, я также должен быть осторожен с блокировкой, так как функция OnSimulationStep () должна позволять запускать каждый шаг симуляции.

Я смотрел на это уже несколько дней и попытался посмотретьна уроках по winsock, но я не программист на C ++ и чувствую себя довольно застрявшим.Пожалуйста, кто-нибудь будет достаточно любезен, чтобы дать мне несколько указаний в правильном направлении?

Заранее спасибо, все советы очень ценятся.

Ответы [ 3 ]

1 голос
/ 17 мая 2011

Я бы лично пошел с boost :: asio, чтобы избавить себя от хлопот при работе с асинхронным вводом-выводом.

Его относительно просто использовать, и он хорошо работает в среде плагинов - я сделал нечто подобное (также в VBS2).

0 голосов
/ 18 мая 2011

Вы можете реализовать TCP-сервер, который хранит входящие сообщения в упорядоченном списке. В каждом OnSimulationStep вы затем запрашиваете на TCP-сервере полученные сообщения и применяете их к VBS2 через ExecuteCommand.

Не забывайте использовать ExecuteCommand всегда в потоке, который вызывает OnSimulationStep. Это означает, что вы не можете выполнять входящие сообщения непосредственно на TCP-сервере.

0 голосов
/ 11 мая 2011

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

Одним из вариантов является очередь в вашем плагине и рабочий поток, который перекачивает данные из очереди в сокет. С дополнительным потоком вы можете просто использовать потенциальный блокирующий вызов. Если блокирующий вызов является проблемой для вас, вы можете установить сокет в неблокирующий режим и подождать с помощью WSAAsyncSelect событие, указывающее, что вы можете снова выполнить запись в одноранговый узел.

...