toLocal8bit 通过 TCP 发送
toLocal8bit send over TCP
我在QT Creator框架中创建TCP服务器/客户端应用程序。我想从UI输入字段中获取一些数据并通过TCP发送。
我在客户端应用程序中做这样的事情:
void MainWindow::on_btn_login_clicked()
{
QByteArray text = (ui->login_input->text()).toLocal8Bit();
char* out = text.data();
connection->ConnectAndSendData(out);
}
在 ConnectAndSendData 函数中:
void TcpConnect::ConnectAndSendData(const char* data)
{
socket = new QTcpSocket(this);
int port = 1234;
socket->connectToHost("localhost", port);
if(socket->waitForConnected(3000))
{
qDebug() << "connected to s. localhost at port " << port;
socket->flush();
socket->write(data, sizeof(data));
qDebug() << data << "n";
socket->waitForReadyRead();
char* serverresponse;
socket->read(serverresponse, 128);
if(serverresponse == MESSAGE_LOGINRQ)
socket->write(data);
socket->flush();
socket->close();
}
else
{
/**/
}
}
行 socket->write(data, sizeof(data)); 中的数据被正确发送到服务器,但是当服务器回显它时,它看起来像"something/x00/x00/x00/x00/x00"或类似的东西。同样当我做这样的事情时:
#define MESSAGE_WANTLOGIN "wanlogin"
socket->write(MESSAGE_WANTLOGIN, sizeof(MESSAGE_WANTLOGIN));
消息被这些空符号弄乱了。
在服务器端接收数据看起来很简单:
void Thread::readyRead()
{
socket->flush();
QByteArray data = socket->readAll();
qDebug() << "data received: " << data;
if(data == MESSAGE_WANTLOGIN)
{
socket->write(MESSAGE_LOGINRQ);
} else
{
qDebug() << "error not messageloginrq";
}
}
就像您可以假设的那样,尽管我发送了"wanlogin"消息,但服务器收到类似"wanlogin/x00/x00"的内容,这显然返回 false。
这个垃圾桶被应用于数据的末尾,这不可能检查发送了什么消息。另一件事是发送数据的最大大小为 8 个字符,但也应用于此长度的数据垃圾,因此它看起来像"wanlogin/x00/x00";但是,当我键入更多字符(例如 10)时,发送数据只是剪切到 8 个符号,没有/x00。
所以我的问题是如何从那些/x00 中清除数据以及如何发送超过 1 字节的信息(我需要它,例如发送用户的登录名和密码)。抱歉,如果有一些愚蠢的错误,这是我的第一个客户端/服务器应用程序,它也为每个客户端使用多线程。
sizeof(data)
是4
还是8
,具体取决于您使用的是 32 位还是 64 位计算机。它不是数据的大小,而是指针的大小(以字节为单位)。
因此,发生的情况是,您的实际wanlogin
实际上是一个 6 个字符的字符串,您最终会再发送 2 个字节。在这种情况下,您很幸运:data()
返回的 char 数组以 null 结尾,因此您可以访问一个额外的0
,但访问第二个0
是未定义的行为,即任何事情都可能发生。
解决方案是使用strlen()
而不是sizeof
.或者,更好的是,通过将ConnectAndSendData(const char* data)
更改为ConnectAndSendData(const QByteArray &data)
来直接用QByteArray
调用write()
。
void MainWindow::on_btn_login_clicked()
{
const QByteArray text = (ui->login_input->text()).toLocal8Bit();
connection->ConnectAndSendData(text);
}
void TcpConnect::ConnectAndSendData(const QByteArray & data)
{
socket = new QTcpSocket(this);
quint16 port = 1234;
socket->connectToHost("localhost", port);
if(socket->waitForConnected(3000))
{
qDebug() << "connected to s. localhost at port " << port;
socket->write(data);
...
}
...
}
- TCP 服务器的异步读取使用 boost::asio 打印客户端套接字发送的数据
- 为什么当通过 TCP 发送的消息速率增加时,请求-响应消息对的延迟会降低?
- 如何将 c++ 中的客户端 TCP 的替身列表发送到 Matlab 中的 TCP 服务器?
- 通过 tcp 发送 C# 类并在 C++ 上反序列化
- 如何使用 TCP 连接发送大块数据
- Visual Studio(C++):如何使用TCP套接字发送多个值
- 是否有一种标准化的方法通过TCP/IP网络发送JPG图像
- 通过TCP将数据从C++客户端发送到JSON服务器
- 如何将通过TCP发送数据的数据从C++转换为Java
- 通过 TCP 套接字发送大型 base64 字符串
- 仅通过建立一次TCP连接将Recv从客户端发送到服务器套接字
- TCP/IP - 以 C/C++ 格式发送十六进制数据包以控制中继板
- 如何<double>通过TCP套接字将CLI 列表^发送到本机C++?
- 如何在 TCP 侦听器中处理异步发送和接收
- 在服务器关闭的TCP连接上发送数据时的行为不一致
- 如何通过TCP/IP Winsock发送双型数据
- TCP-Server以数据包结构(非Java客户端)发送文件
- 通过C 中的TCP/IP协议发送.TXT文件
- toLocal8bit 通过 TCP 发送
- 从c++发送TCP数据并接收到Java套接字