简体   繁体   中英

C++ TCP Socket Plugin

I am currently working with the simulation engine VBS2 and am attempting to write a TCP socket plugin. I have a client application which I want to connect to the plugin and send a single message. Perhaps this will make more sense if I post the existing plugin code:

#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;
}

The message sent to the plugin will be used in the OnSimulationStep() function by being passed as an argument to ExecuteCommand(). However, I've also got to be careful about blocking here as the OnSimulationStep() function must be allowed to run every simulation step.

I've been staring at this for a few days now and have tried looking at the winsock tutorials, but I'm not a C++ programmer and am feeling rather stuck. Please would anyone be kind enough to give me a few pointers in the right direction?

Thanks in advance, all advice is greatly appreciated.

I would personally go with boost::asio to save myself all the hassle in dealing with asynchronous IO.

It is relatively straightforward to use, and it works well in the plugin environment - I've done something similar (also in VBS2).

When your plugin must handle data in a short time and you fear that the winsock send function could block, you need to queue the data or write a mechanism that only the important data is written, if this is an option.

One option is a queue in your plugin and a worker thread that pumps the data from the queue to the socket. With the additional thread you can just use a potential blocking call. If the blocking calll is a problem for you, you can set the socket to non-blocking mode and and wait with WSAAsyncSelect for an event indicating that you can write to the peer again.

You could implement an TCP-server which stores incoming messages in an ordered list. In each OnSimulationStep you then query the TCP-server for received messages and apply them to VBS2 via ExecuteCommand.

Remember to use ExecuteCommand always in the thread which calls OnSimulationStep. This means you're not able to execute incoming messages directly in the TCP-server.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM