如何通过套接字读取从PHP发送到Qt服务器应用程序的字符串
How do I read a string sent from PHP through a socket to a Qt server application?
我真的很难阅读通过套接字连接发送到Qt服务器应用程序的字符输入。数据从PHP发送。
我理解读取流数据的原则,因为我已经在堆栈上问过了。我也得到了它的工作使用服务器和客户端都写在Qt。
我使用的方法是在实际数据之前附加我要发送的数据的字节大小。然后,当数据传入时,我首先读取长度parth,这样我就确切地知道我需要读取多少字节才能获得正确格式的数据。
它看起来像这样:
发送功能:
void Client::sendNewMessage(){
qDebug() << "sendNewMessage()";
QString string(messageLineEdit->text());
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0);
out << quint16(0);
out << string;
out.device()->seek(0);
out << (quint16)(block.size() - sizeof(quint16));
tcpSocket->write(block);
}
接收功能:
QDataStream in(tcpServerConnection);
in.setVersion(QDataStream::Qt_4_0);
qDebug() << "bytes available = " << tcpServerConnection->bytesAvailable();
if (blockSize == 0) {
int size = (int) sizeof(quint16);
qDebug() << "size = " << size;
if (tcpServerConnection->bytesAvailable() < (int)sizeof(quint16)){
qDebug() << "less bytes than size...";
return;
}
qDebug() << "bytes available=" << tcpServerConnection->bytesAvailable();
in >> blockSize;
}
if (tcpServerConnection->bytesAvailable() < blockSize){
qDebug() << "less bytes available than blocksize, bytes="
<< tcpServerConnection->bytesAvailable();
return;
}
QString data;
in >> data;
qDebug() << "data = " << data;
好了,这些都能运行所以我试着用PHP做但是失败了
这是我的一个尝试:
<?php
$addr = gethostbyname("127.0.0.1");
$client = stream_socket_client("tcp://$addr:*****", $errno, $errorMessage);
if ($client === false) {
throw new UnexpectedValueException("Failed to connect: $errorMessage");
}
$data = 'a';
$datatopost = serialize($data);
fwrite($client, strlen($data));
fwrite($client, base64_encode($data));
echo stream_get_contents($client);
fclose($client);
在Qt中,我尝试了各种组合的quint8, 16, 32, 64, sizeof(char), sizeof(int)。
在PHP我已经尝试序列化数据,编码,并发送它没有所有的东西。但是我不能让它工作。我必须非常接近,虽然,因为数据实际上是发送的,因为有可用的字节,但我不知道如何正确编码/解码它的工作。
在问了关于这个话题的各种问题之后,我确实觉得我的理解提高了很多,但是关于如何实际做事的重要信息对我来说仍然缺失。
所以我的问题:这里出了什么问题,需要采取哪些步骤才能从PHP读取数据到Qt/c++ ?
细节非常感谢,因为我真的很想知道事情是如何从内到外工作的。
边注从PHP脚本发送数据后,服务器也发送数据回来,这是有效的。所以连接成功了
这是实际也收到回复的工作PHP脚本:
<?php
if(!($sock = socket_create(AF_INET, SOCK_STREAM, 0)))
{
perror("Could not create socket");
}
echo "Socket created n";
//Connect socket to remote server
if(!socket_connect($sock , '127.0.0.1' , *****))
{
perror("Could not connect");
}
echo "Connection established n";
$message = "aa";
//Send the message to the server
if( ! socket_send ( $sock , $message , strlen($message) , 0))
{
perror("Could not send data");
}
echo "Message send successfully n";
//Now receive reply from server
if(socket_recv ( $sock , $buf , 500 , MSG_WAITALL ) === FALSE)
{
perror("Could not receive data");
}
echo $buf;
///Function to print socket error message
function perror($msg)
{
$errorcode = socket_last_error();
$errormsg = socket_strerror($errorcode);
die("$msg: [$errorcode] $errormsg n");
}
从浏览器url:
执行时的脚本回复Socket created nConnection established nMessage send successfully n hello
不集成PHP代码并不奇怪。如前所述,您必须意识到QDataStream实现了自定义序列化。如前所述,您可能想要使用(read|write)RawData,或者(read|write)Bytes,如果您读取的是以前没有使用QDataStream序列化的内容。但是,您尝试从PHP 编写字符串数据的一般思路应该与Qt编码字符串(长度然后是一系列字符)的方式兼容。反正手册是这么说的…)。但还是有一些问题。
- QString为2Byte Unicode。
- PHP字符串是任意类型的ASCII兼容数据的字节数组- PHP字符串详细信息。
-
这个位有一些问题:
fwrite($client, strlen($data)); fwrite($client, base64_encode($data));
strlen()
返回底层存储中的字节数(这是ASCII字符串的实际字节长度)。Base64_encode()改变字符串中的字节数。假设fwrite()正在写一个四字节的整数。 -
我们还在猜测
QString data; in >> data;
确实有效。
一般建议是,您必须仔细定义外部二进制api。
这个任务需要数据序列化吗?您的PHP客户端和Qt服务器可能使用不同的格式。尝试发送和接收原始数据。
下面是一个简单的QTcpServer
示例:
class DataReceiver : public QObject
{
Q_OBJECT
public:
explicit DataReceiver(QObject *parent = 0);
public slots:
void start(quint16 port = 9090);
private slots:
void newTcpConnection();
private:
QTcpServer server;
};
DataReceiver::DataReceiver(QObject *parent) :
QObject(parent)
{
connect(&server, SIGNAL(newConnection()), this, SLOT(newTcpConnection()));
}
void DataReceiver::start(quint16 port)
{
bool isOk = server.listen(QHostAddress::Any, port);
if (isOk && server.isListening())
{
qDebug() << "QTcpServer started on port" << port;
}
else
{
qCritical() << "Failed to start QTcpServer";
}
}
void DataReceiver::newTcpConnection()
{
qDebug() << "New incoming connection";
QTcpSocket *socket = server.nextPendingConnection();
QByteArray data;
while (true)
{
QByteArray tmp = socket->readAll();
data += tmp;
if (tmp.isEmpty() && !socket->waitForReadyRead())
{
break;
}
}
socket->deleteLater();
qDebug("Data received: %s (len = %d)", data.constData(), data.length());
}
启动服务器:
#include <QCoreApplication>
#include "data_receiver.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
DataReceiver d;
d.start();
return a.exec();
}
您可以使用PHP客户端向它发送数据:
<?php
$addr = gethostbyname("127.0.0.1");
$port = 9090;
$data = 'hello from php';
$client = stream_socket_client("tcp://$addr:$port", $errno, $errorMessage);
if ($client === false) {
throw new UnexpectedValueException("Failed to connect: $errorMessage");
}
fwrite($client, $data);
fclose($client);
或者您可以使用nc
实用程序:
echo -n "hello from nc" | nc 127.0.0.1 9090
以下是两种情况下的服务器输出:
QTcpServer started on port 9090
New incoming connection
Data received: hello from php (len = 14)
New incoming connection
Data received: hello from nc (len = 13)
- 在 Ubuntu 服务器上运行 QT 应用程序时崩溃
- Qt TCP服务器不从客户端读取数据
- 将移动设备(iOS和Android)连接到带有QT / C++和镜像显示的VNC服务器
- 如何在Qt c++中使用Secure WebSocket与服务器连接
- 如何在Qt中使UDP"客户端",以便他从服务器接收数据?
- Qt C++ 带有 Python 客户端的 SSL/TLS 服务器
- 使用 QT 开发服务器应用程序是个好主意吗?(QT5)
- NAS(使用 qt/linux)- 无法建立简单的音频服务器连接测试
- 从QT Web服务器处理多个客户端
- QT-简单的HTTP服务器
- 错误请求,您的浏览器发送了此服务器无法理解的请求 - Qt Websocket 服务器
- 如何在Qt中获取主DNS服务器和辅助DNS服务器
- Qt websocket,连接到服务器
- Qt,客户端-服务器关系
- Qt服务器客户端代码
- Qt:服务器应该广播变化的值,客户端应该侦听它
- 非QT服务器和QT客户端-使用节俭连接
- 如何通过套接字读取从PHP发送到Qt服务器应用程序的字符串
- Android网络连接.可以写数据,但不能读数据.使用QT服务器
- QT服务器端写入功能出错(在线程0..中停止)