【问题标题】:C++ TCP Socket PluginC++ TCP 套接字插件
【发布时间】:2011-05-11 14:20:12
【问题描述】:

我目前正在使用模拟引擎 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;
}

发送到插件的消息将通过作为参数传递给 ExecuteCommand() 在 OnSimulationStep() 函数中使用。但是,我还必须小心这里的阻塞,因为必须允许 OnSimulationStep() 函数运行每个模拟步骤。

我已经盯着这个看了几天,并尝试查看winsock 教程,但我不是 C++ 程序员,感觉有点卡住了。请有人好心给我一些正确方向的指点吗?

提前致谢,非常感谢所有建议。

【问题讨论】:

  • 如果您告诉我们您想要完成什么,将会有所帮助。如果您想以艰难的方式做某事,我们可以建议一个更简单的替代方案。您真的需要 tcp 还是只是对在进程/线程之间传递消息感兴趣?
  • 恐怕我不太清楚你的意思;我试图让插件监听来自客户端的传入消息,如果收到消息,则将其传递给ExecuteCommand()。我之所以选择 TCP,是因为我知道用 C# 编写的客户端是为 TCP 编写的。这样的回答你的问题吗?谢谢
  • 还有其他技术可能更容易或更好地解决您的问题。如果我们不知道您的要求或您试图解决的问题,我们可以提供的帮助有限。我们找不到离开森林的路,因为你只告诉我们一棵树。你考虑过 MSMQ 还是 WCF?
  • 我最诚挚的歉意,但我真的不明白你不知道问题的意思;这个问题真的和我之前说的一样简单。该插件是相关程序的 ASI。我有一个单独的客户端,用 C# 编写,它试图通过 TCP 连接并发送有效的脚本消息,例如插件“0 setOvercast 1”中的示例。我只是想接收这些消息并将它们作为参数传递给ExecuteCommand()。我没有隐瞒任何事情;没有什么比这更复杂了——MSMQ 和 WCF 似乎使问题变得过于复杂。继续...
  • ...我绝不希望遇到粗鲁或忘恩负义,我真的很感激时间和精力,我只是在努力理解问题中缺少哪些信息。我很乐意提供更多信息,但我不确定需要更多信息。 :)

标签: c++ windows sockets plugins tcp


【解决方案1】:

我个人会选择 boost::asio 来省去处理异步 IO 的所有麻烦。

它使用起来相对简单,并且在插件环境中运行良好 - 我做过类似的事情(也在 VBS2 中)。

【讨论】:

    【解决方案2】:

    当你的插件必须在短时间内处理数据时并且你担心winsocksend函数会阻塞,你需要对数据进行排队或者写一个只写入重要数据的机制,如果这是一个选项。

    一个选项是插件中的队列和将数据从队列泵送到套接字的工作线程。使用附加线程,您可以只使用潜在的阻塞调用。如果阻塞调用对您来说是个问题,您可以将套接字设置为非阻塞模式并使用WSAAsyncSelect 等待指示您可以再次写入对等方的事件。

    【讨论】:

      【解决方案3】:

      您可以实现一个 TCP 服务器,它将传入的消息存储在有序列表中。然后在每个 OnSimulationStep 中查询 TCP 服务器接收到的消息并通过 ExecuteCommand 将它们应用到 VBS2。

      请记住始终在调用 OnSimulationStep 的线程中使用 ExecuteCommand。这意味着您无法直接在 TCP 服务器中执行传入消息。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-12-14
        • 1970-01-01
        • 1970-01-01
        • 2018-04-03
        • 2014-04-17
        • 2017-11-01
        • 1970-01-01
        • 2014-05-18
        相关资源
        最近更新 更多