【问题标题】:C++ Builder TtcpClientC++ 生成器 TtcpClient
【发布时间】:2012-01-31 13:09:07
【问题描述】:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    int size =  MemoEnter->GetTextLen() + 1;
    wchar_t *szBuff = new wchar_t[size];
    memset(szBuff, 0, sizeof(szBuff));
    MemoEnter->GetTextBuf((wchar_t *)szBuff, size);
    TcpClient->SendBuf(szBuff, sizeof(szBuff));
    LogOut->Lines->Add(szBuff);
    delete []szBuff;
}  

为什么 TcpClient 不发送任何东西? 服务器没问题。连接正常。 Telnet 向服务器发送数据,但这段代码没有。

伙计们!我试过了

TcpClient->SendBuf("fsd", 3);

还是一无所获

【问题讨论】:

  • TcpClient 连接正常吗?没有错误/异常?

标签: c++ tcp c++builder c++builder-xe2


【解决方案1】:

这可能会导致问题:

sizeof(szBuff); // Returns the sizeof a wchar_t*,
                // not the number of characters in szBuff

变化:

memset(szBuff, 0, sizeof(szBuff));
...
TcpClient->SendBuf(szBuff, sizeof(szBuff));

收件人:

memset(szBuff, 0, sizeof(wchar_t) * size);
...
TcpClient->SendBuf(szBuff, wcslen(szBuff));

如果TcpClient->SendBuf()的第二个参数是字节数,而不是字符数,则改为:

TcpClient->SendBuf(szBuff, wcslen(szBuff) * sizeof(wchar_t));

【讨论】:

  • 不。问题出在 TcpClient 组件中。 memset 工作正常。
  • TcpClient 只是不发送任何内容
【解决方案2】:

您对sizeof() 的使用肯定是问题所在。您发送的数据指定了指向缓冲区的指针的大小,而不是缓冲区本身的大小。指针的大小在 32 位中为 4,在 64 位中为 8。您需要使用实际缓冲区大小而不是指针大小。

您应该使用 VCL 的 String 类而不是使用 new[] 运算符,例如:

void __fastcall TForm1::Button1Click(TObject *Sender) 
{ 
    String s = MemoEnter->Text; 
    TcpClient->SendBuf(s.c_str(), ByteLength(s)); 
    LogOut->Lines->Add(s); 
}

请注意,StringUnicodeString 的别名。如果接收方不期待UTF-16编码的数据,那么您需要在发送之前将数据转换为另一种编码,例如:

void __fastcall TForm1::Button1Click(TObject *Sender) 
{ 
    String s = MemoEnter->Text; 
    UTF8String utf8 = s;
    TcpClient->SendBuf(utf8.c_str(), utf8.Length()); 
    LogOut->Lines->Add(s); 
}

或者:

void __fastcall TForm1::Button1Click(TObject *Sender) 
{ 
    String s = MemoEnter->Text; 
    AnsiString ansi = s; // <-- potential data loss for non-ASCII characters!
    TcpClient->SendBuf(ansi.c_str(), ansi.Length()); 
    LogOut->Lines->Add(s); 
}

或者:

void __fastcall TForm1::Button1Click(TObject *Sender) 
{ 
    String s = MemoEnter->Text; 
    AnsiStringT<SomeCodePage> ansi = s; // <-- use a suitable codepage to avoid data loss!
    TcpClient->SendBuf(ansi.c_str(), ansi.Length()); 
    LogOut->Lines->Add(s); 
}

【讨论】:

  • 感谢您提供有趣的信息,但仍然没有发送任何内容。我的意思是 id 不会发送一点数据。只是什么都没有。
  • SendBuf()的实际返回值是多少?它返回套接字的出站缓冲区接受的字节数,或 -1 出错。
  • 它打印数字 22。在docwiki.embarcadero.com/VCL/en/… 它说返回值是发送的字节数
  • 该文档适用于TCustomWinSocket,而不是TTcpClient。但无论如何,任一组件中SendBuf() 的返回值是成功放入套接字内部发送缓冲区的字节数,而不是通过网络发送的字节数。操作系统在后台处理实际传输。该应用程序无法知道实际传输何时发生。如果SendBuf() 返回22,那么套接字真的接受了22 字节,它不在你的掌控之中。现在您需要仔细检查接收端的代码是否正常工作。
  • 使用数据包嗅探器(如 Wireshark)来验证和查看操作系统何时通过网络传输数据,以及数据何时到达另一端。
猜你喜欢
  • 1970-01-01
  • 2011-04-05
  • 2015-10-13
  • 1970-01-01
  • 1970-01-01
  • 2010-09-10
  • 2010-12-10
  • 2021-07-01
  • 2017-03-31
相关资源
最近更新 更多