繁体   English   中英

MailSlot写三次C / C ++发送相同的东西

[英]MailSlot write sending same thing three times C/C++

我在Windows(C / C ++)中的MailSlots有问题。

我正在努力制作两个简单的程序,但最后一步的沟通并不好。

这是我在server.cpp中的int main

    int main()
{
HANDLE      ss, sc, sc2r;
   LPCTSTR     errMsg;

   ss = CreateMailslot("\\\\.\\mailslot\\ss", 0, MAILSLOT_WAIT_FOREVER, NULL);
   if (ss == INVALID_HANDLE_VALUE) 
   {
       printf("Invalid ss value");
       return -1;
   }

   for (;;)
   {
       DWORD   msgSize;
       DWORD nr;
       BOOL    err;

       /* Get the size of the next record */
       err = GetMailslotInfo(ss, 0, &msgSize, 0, 0);
           char x[100];
           char nrr[10];

       if (msgSize != (DWORD)MAILSLOT_NO_MESSAGE)
       {
               DWORD   numRead;
               /* Read the record */
               err = ReadFile(ss, x, msgSize, &numRead, 0);
               int wrds=count(x)+1;
               sc = CreateFile("\\\\*\\mailslot\\sc", GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
               itoa(wrds,nrr,10);

               err = WriteFile(sc, nrr, sizeof(nrr), &nr, 0);
               //cout<<err<<endl;

               //cout<<x;

               //cout<<err;
               strrev(x);
               err=WriteFile(sc, x, sizeof(x), &nr, 0);
           }   
       }
  return(0);
}

这是客户端来源:

int main()
{
   HANDLE      ss, sc, sc2;
   LPCTSTR     errMsg;
   BOOL        err;
   DWORD       numWritten;

   sc = CreateMailslot("\\\\.\\mailslot\\sc", 0, MAILSLOT_WAIT_FOREVER, NULL);
   ss = CreateFile("\\\\*\\mailslot\\ss", GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

   if (ss == INVALID_HANDLE_VALUE) 
   {
       printf("CreateFile failed. ");  
       // Close any mailslot we opened
       if (ss != INVALID_HANDLE_VALUE) CloseHandle(ss);
       return -1;
   }

   char x[100];
   char z[100];

   printf("Write the damn sentence:");
   cin.getline(x,100);
   err = WriteFile(ss, x, sizeof(x), &numWritten, 0);
   if (!err) printf("WriteFile failed. ");
   DWORD rd;

   ReadFile(sc,x,sizeof(x),&rd,NULL);
   cout<<x<<endl;
   ReadFile(sc,z,sizeof(z),&rd,NULL);
   cout<<z;

   return 0;
}

好像服务器发送了三次相同的东西。 我在调试器中测试了客户端并且他正确,但无法弄清楚为什么服务器发送三次相同的东西。

你有什么建议吗 ?

Mailslots是一种不可靠的传输 - 消息可以自由删除。 为了确保消息通过,发送方使用每个可用的不同协议(将该发送方连接到预期的接收方)自动发送消息一次。

您的网络堆栈显然已设置好,因此有三种协议可将您的发送方连接到接收方。 由于它们(可能)在本地进行通信,通过相对可靠的硬件而没有通过丢弃数据包来处理拥塞的路由器,或类似的任何东西,您可能会获得每个数据包的三个副本。

底线:如果你想使用邮件槽,你几乎必须为每个数据包分配一个序列号,这样你就可以跟踪你已经收到的东西,这样你就能识别并忽略在接收方重复。

或者,只是不要使用邮件槽。 如果(无论出于何种原因)您需要特定于Windows的内容,则命名管道通常更容易。 除非你的代码实际上受到可移植性和可互操作性的困扰,否则套接字可能仍然更简单。

你把sizeofstrlen混淆了。 调用sizeof(nrr)将始终返回10.服务器程序将执行10个字节的单次写入,即使缓冲区仅包含2个有效字节。

1+strlen替换sizeof以解决问题。

例如,在server.cpp中,如果wrds为1,则nrr将在内存中为{ 0x31, 0x00 } nrr { 0x31, 0x00 } 看起来像重复写入的内容实际上是对未初始化内存的单次写入。 strlen将为您提供有效字符数,+1表示终止空值。

初始化nrr可能是个好主意,首先使用*nrr = 0 您可以使用if(*nrr)测试itoa if(*nrr)并按您认为合适的方式处理故障。

哦,还有一件事:你正在泄漏手柄。 在客户端中可能没什么关系,但是服务器在每次迭代时都会泄漏邮件槽的句柄。 您应该重复使用mailslot句柄或在每次迭代时关闭它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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