文章 "在MQL中操作套接字,或者如何成为信号提供者" - 页 2

 
Alexey Volchanskiy:
这里是低级网络编程论坛吗?)))
这篇文章揭示了新的可能性,而不是对你的知识进行测试。

想在以下领域学习和使用客户服务器技术的人

- 复印机
- 新闻简报
- 信号分发
- 交易信息交换
他注意到并使用它。

但你的情况不是这样,你只是不在这个圈子里、

因此,请放心通过。

我会删除 flud。

 
o_O:
这篇文章揭示了新的可能性,而不是对您的知识进行测试。

希望在以下领域学习和使用客户服务器技术的人

- 复印机
- 新闻简报
- 信号分发
- 交易信息交流
他记下来并加以使用。

但你的情况不是这样,你只是不在这个圈子里、

因此,请放心通过。

灌水将被删除。

做得很好,很整洁,不用着急、

将那些愚蠢的套接字结构映射到 MQL 基础上。

非常清晰明了。这里是 https://www.mql5.com/zh/articles/1361。

也是关于相同的套接字主题,但可能非常繁琐、

对于简单的任务,作者提出的方法更可取......

感谢作者, 例如对我来说,它与当前项目 非常相关,我会使用它...

 
有没有可能在不使用第三方 dll 的情况下,在 mql4 上实现同样的功能。
 
Dmitry Melnichenko:
有没有办法在不使用第三方 dll 的情况下在 mql4 上实现同样的功能?

有。文章中给出的所有代码在 mql4 中都能以类似方式重现,但您仍然必须使用 Windows dll。

 

我不明白,当一个人分享如此严肃的话题时,为什么会有这么多人持怀疑态度。难道是嫉妒有人知道,而其他人却不知道这是什么?

尤其是现在每个人都有机会了解这个话题。

 
Dmitry Fedoseev:

我不明白,当一个人分享如此严肃的话题时,为什么会有这么多人持怀疑态度。难道是嫉妒有人知道,而其他人却不知道这是什么?

尤其是现在每个人都有机会了解这个话题。

公告写得不完整。人们并没有阅读这篇文章(像往常一样,没有人会阅读说明:),于是出现了一整页的絮絮叨叨。直到我通俗地解释说,在评论文章之前最好先阅读全文。
 

文章中的代码是错误的。你根本没有考虑结构的对齐情况。

// x86
typedef struct WSAData
{
  ushort wVersion;             // 2
  ushort  wHighVersion;        // 2
  char szDescription[256+1];   // 257
  char szSystemStatus[128+1];  // 129
  ushort iMaxSockets;          // 2
  ushort iMaxUdpDg;            // 2
                               // +2 插入以获得对齐方式 4(如果我没弄错的话,位置是不准确的,编译器可以把它放在任何它想放在的地方)
  char  *lpVendorInfo;         // 4
}; // sizeof(WSAData) == 400

// x64
typedef struct WSAData
{
    WORD                    wVersion;                              // 2
    WORD                    wHighVersion;                          // 2
    WORD                    iMaxSockets;                           // 2
    WORD                    iMaxUdpDg;                             // 2
    char                   *lpVendorInfo;                          // 8 
    char                    szDescription[WSADESCRIPTION_LEN+1];   // 257
    char                    szSystemStatus[WSASYS_STATUS_LEN+1];   // 129
                                                                   // +6 插入以获得对齐 8
}; // sizeof(WSAData) == 408

// 您的 mql 结构
struct WSAData
  {
   WORD              wVersion;                              // 2
   WORD              wHighVersion;                          // 2
   char              szDescription[WSADESCRIPTION_LEN+1];   // 257
   char              szSystemStatus[WSASYS_STATUS_LEN+1];   // 129
   ushort            iMaxSockets;                           // 2
   ushort            iMaxUdpDg;                             // 2
   char              lpVendorInfo[];                        // x64 上 8 个,x86 上 4 个
  }; // sizeof(WSAData) == 402(x64), 398(x86)
x64 中结构体的大小 是基于指针对齐 == 8(最有可能是 8)这一假设的理论计算结果。但举例来说,结构体中的 alignof(double) == 4,而结构体外的 alignof(double) == 8。这就是我不能百分百确定的原因)。但即使是 4,结构体在 x64 中的大小也将是 404,而不是 408。无论如何,你在 x86 和 x64 下的 WSData 都溢出了缓冲区。 在撰写文章之前,你应该进行最简单的 sizeof() 测量,并明确指定代码所针对系统的位数(因为你已经开始复制系统结构)。我说的不是结构的未对齐初始地址。我没有检查过整个代码,也许其他结构也有问题。

顺便说一下,如果 MKL 团队的人看到这条信息:您的所有地址都是未对齐的,为什么?现代处理器已经足够智能,所有型号都能读取数据?以性能损失的形式收取一点费用,但不会有更多问题(不会像死机那样)。
 

但我说得不太对。在 MQL 中,WSData 的大小会比需要的大得多(lpVendorInfo[] 是一个 大小约为 50 的动态数组,而不是指针)。因此,代码应能正常工作。但这只是一个意外,你很幸运,而不是正确的理论假设。MKL 结构本身是无效的,最好是创建一个足够大的数组,而不要声明任何东西。如果你写

WSADatat wsdata
int res=WSAStartup(MAKEWORD(2,2), &wsadata);

// вместо
char wsaData[]; ArrayResize(wsaData,sizeof(WSAData));
int res=WSAStartup(MAKEWORD(2,2), wsaData);
就会出错。
 

是的,在 MQL 中,结构是对齐的https://www.mql5.com/zh/docs/basis/types/classes

根据 WinSock2.h 的内容判断,WSAData 结构没有 #pragma pack(1),因此如你所说,其大小可能超过 µl。

但我可以说,要么是哪里出了问题,要么是这些数据没有杀死堆栈,但使用这些套接字的所有 mcl 软件都能稳定运行数月,没有出现过终端重载的情况。

如果能从头到尾搞清楚就好了。

 
只需按样式重写即可:
#define  WSA_DATA_SZ   420
...
char wsaData[WSA_DATA_SZ];
int res=WSAStartup(MAKEWORD(2,2), wsaData);
不用担心对齐问题,也不用担心编译器会把多余的字节放在哪里。反正你也不会访问任何字段,那么这种令人头疼的结构声明又有什么意义呢?