Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 通过套接字发送数据的过程实际上是如何工作的?_Php_C++_Qt_Sockets_Stream - Fatal编程技术网

Php 通过套接字发送数据的过程实际上是如何工作的?

Php 通过套接字发送数据的过程实际上是如何工作的?,php,c++,qt,sockets,stream,Php,C++,Qt,Sockets,Stream,我已经编写了一个服务器/客户机设置,可以来回发送字符串,并且可以正常工作。现在我试图从一个不起作用的php脚本发送数据,所以我试图解释为什么它不起作用 这是从客户端发送数据的代码,字符串I发送到server=“aa” (注意代码中的注释) void客户端::sendNewMessage(){ qDebug()text()); QByteArray区块; QDataStream out(块和QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_

我已经编写了一个服务器/客户机设置,可以来回发送字符串,并且可以正常工作。现在我试图从一个不起作用的php脚本发送数据,所以我试图解释为什么它不起作用

这是从客户端发送数据的代码,字符串I发送到server=“aa”

(注意代码中的注释)

void客户端::sendNewMessage(){
qDebug()text());
QByteArray区块;
QDataStream out(块和QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0);
out blockSize;//我注意到这行执行之后
//tcpServerConnection->bytesAvailable被2减去
//blockSize=8而不是10,因为
//tcpServerConnection->bytesAvailable从10开始。
//似乎套接字识别出追加了一个quint16
//在实际数据之前,因此为8字节。是否正确?
if(tcpServerConnection->bytesavable()>数据中;
qDebug()TCP是一种字节流协议,这意味着数据以有序的字节流发送和接收,而不保留任何逻辑消息边界。在这方面,当终端设置为无缓冲模式时,读取数据有点像读取
std::cin
:您可能会得到用户键入的下一个字符,或10个字符,或完整的一行、一行半或下一个4k。您唯一可以确定的是,您无法获得写入流中的数据。这取决于您是否有足够的数据进行有意义的处理:可能是通过

  • 扫描哨兵字符,如
    “\n”
    ,知道完整的输入行是值得处理的独特的“逻辑”消息

  • 为下一条逻辑消息预加长度,可以是固定长度字段(更容易),也可以是可变长度文本,后跟空格或换行符等已知分隔符;这就是代码使用2字节
    quint16
    大小
    值所做的

  • 将每个逻辑消息填充为固定长度

然后有必要保持
read()
ing或
recv()
ing,直到读取足够的字节以处理下一条逻辑消息

似乎你的
QDataStream
通过
read()
ing/
recv()
ing尽可能地让你更容易做到这一点-可能是在后台线程中,或者当你的应用程序处于空闲状态时。它显然提供了
bytesavable()
作为已从TCP流接收并在其缓冲区中的字节计数

在客户端:

QString string(messageLineEdit->text()); 
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0);
out << quint16(0) << string; // why is the quint16 appended before the string?

这会在字符串之前跳回到上面写入2字节“0”值的位置

out << (quint16)(block.size() - sizeof(quint16)); // substract 16bit unsigned int from the total data size? 

out bytesavable()

@cantofything:想法不错,尽管
quint16
是两个字节,而不是位。
seek(0)
这件事很愚蠢,因为字符串的大小必须可以直接写入文件,而不需要这样的诡计。”这会跳回到字符串前面的2字节“0”的位置“值写在上面…”由于套接字是顺序的,因此对它们进行搜索毫无意义,是不可操作的。这是有记录的:顺序设备不支持搜索任意位置。数据必须一次读取。函数
pos()
size()
不适用于顺序设备。
qtcsocket
QProcess
都是顺序设备的示例。唉,当然你不是在将它写入套接字,而是写入缓冲区,所以我所说的查找是正确的,但不适用于这里。
QBuffer
不是顺序设备。很抱歉,这里有噪音。@canthinkofathing关于2个步骤而不是3个步骤的是(如果您计算写入0长度、写入字符串、查找、写入正确长度,则为4个步骤)。不客气。别忘了纠正上一段中提到的错误-当您的程序通过较慢/不太可靠的网络连接和/或在负载较多/繁忙的计算机上传输大量数据时,这类错误最有可能导致失败。Cheers@CantThinkOfAnything:是的,这就是它的工作方式。。。正确。谢谢这些套接字是顺序I/O设备,对它们进行搜索是不可操作的。不要对它们进行搜索!…但代码中的第一次搜索是有效的。您在缓冲区而不是套接字上进行搜索:)@KubaOber aaah是的,我已经从下面的评论中得到了这一点:D谢谢!!
QString string(messageLineEdit->text()); 
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0);
out << quint16(0) << string; // why is the quint16 appended before the string?
out.device()->seek(0); // set current position to 0, why exactly?
out << (quint16)(block.size() - sizeof(quint16)); // substract 16bit unsigned int from the total data size?