是否可以创建一个新的QSslSocket并使其获得现有TCP连接的所有权,并且旧的QTcpSocket将被丢弃,而不会中断或关闭TCP连接?
我需要这个在我的FTP服务器中实现显式FTPS,这要求最初连接是未加密的,并且只有在FTP客户端的请求(命令AUTH SSL或AUTH TLS)时,如果它发生,则启动SSL/TLS握手.
现在服务器(用java实现)会向我发送一些流数据,我的代码如下:
connect(socket, SIGNAL(readyRead()), this, SLOT(read_from_server()));
Run Code Online (Sandbox Code Playgroud)
在read_from_server():
{
while (socket->bytesAvailable())
{
QString temp = socket->readAll();
}
}
Run Code Online (Sandbox Code Playgroud)
但我发现即使服务器发给我一个只有几个字符的字符串,数据被截断,我的函数被调用两次,因此temp是我想要的永不完整的数据.
如果服务器发给我一个更长的字符串,我的函数可能会被调用三次或更多次,这使得我很难知道数据完全被传输的时间.
所以任何人都可以告诉我如何轻松完全接收数据,没有这么多困扰的步骤?如果这与其他一些问题重复,我很抱歉,我无法让他们的答案适合我.非常感谢!
我正在编写一个程序,每秒向服务器发出 1 个 GET 请求。我正在使用套接字(QTcpSocket),我想知道是否应该在请求中包含“连接:关闭”,然后为每个请求重新创建套接字,或者是否最好简单地保持套接字处于活动状态,因为我正在重复每秒一次相同的请求。
我期待使用PyQt创建一个QTcpServer,它可以同时将数据返回给两个或更多客户端.我认为这需要线程化.
使用threadedfortuneserver.py示例作为测试用例(包含在PyQt4中,在我的系统上,它位于/ usr/share/doc/python-qt4-doc/examples/network中),我想连接多个客户端,每次都需要一个客户要求发财,其他客户也会更新一条消息,例如"客户X刚刚收到财产'等等等等等等."
我理解fortuneserver/client程序是如何工作的,但似乎在将财富发送回客户端后立即终止客户端连接.我的具体问题是:
是否可以保持所有连接处于打开状态,以便每当其中一个客户端请求发财时,其他客户端都可以更新?
如果是这样,跟踪和循环连接的客户端的最佳方法是什么?
这对我来说是一个严重的绊脚石,因为我想开发一个应用程序,其中几个客户端可以进行交互,并且每个客户端都可以更新其他客户端的操作.
在此先感谢您的帮助,如果我能提供任何其他信息,请与我们联系.
我找到了这个帖子,但没有足够的具体信息可供使用.关于Python套接字包的其他讨论,但我的理解是,当使用PyQt时,服务器应该是QTcpServer,所以一切都很好.
***编辑***
以下是我的解决方案的开始阶段.我创建了一个基本的服务器和客户端.服务器只是将客户输入的内容发送回"行编辑"框.
我基于使用Python和Qt的Rapid GUI Programming的第18章中的"buildingservices"示例.
我做的主要改变是现在线程无限期地运行并且它们的套接字保持打开状态,监听客户端发送的数据.
它处理多个客户端很好.这当然很难看,但我认为这是一个很好的起点.
我想要的是能够在一个客户端输入文本时通知每个客户端(比如典型的聊天程序).
另外,为了让您了解自己与谁打交道,我不是专业程序员.我是一名物理学家,拥有多年无纪律的脚本和摆弄我的腰带.但我想尝试开发可以传递数据的基本服务器/客户端程序.
感谢您的任何帮助或建议!
服务器:
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtNetwork import *
PORT = 9999
SIZEOF_UINT16 = 2
class Thread(QThread):
#lock = QReadWriteLock()
def __init__(self, socketId, parent):
super(Thread, self).__init__(parent)
self.socketId = socketId
def run(self):
self.socket = QTcpSocket()
if not self.socket.setSocketDescriptor(self.socketId):
self.emit(SIGNAL("error(int)"), socket.error())
return
while self.socket.state() == QAbstractSocket.ConnectedState:
nextBlockSize = 0
stream = …Run Code Online (Sandbox Code Playgroud) 我有一个与UNIX C++套接字的套接字连接,在连接之后,我有一个循环来逐字节读取,直到我有完整的消息.我知道我要接收的消息的前两个字节,以及它的长度(15个字节).所以函数看起来像:
bool mastControl::findPacket(int sockfd, st_messageMastToPc * messageReceived, bool * connected) {
int n = 0;
bool messageFound = false;
char * buffer = (char *) messageReceived;
unsigned int pos = 0;
while ( ((n = read(sockfd, &(buffer[pos]), 1)) > 0) and not messageFound) {
if (n == 1) {
pos++;
if ( (pos == 1) && (buffer[0] == 0x02)) { // First byte to receive
std::cout << "INFO - Rcv1" << std::endl;
} else if ( (pos == 2) …Run Code Online (Sandbox Code Playgroud) 是否有任何简单的方法将文件发送到包含文件名的服务器,以便服务器和客户端中的文件名完全相同?
这是我的代码
QString path = QApplication::applicationDirPath()+"/belajardansa.bmp";
QFile inputFile(path);
QByteArray read ;
inputFile.open(QIODevice::ReadOnly);
while(1)
{
read.clear();
read = inputFile.read(32768*8);
qDebug() << "Read : " << read.size();
if(read.size()==0)
break;
qDebug() << "Written : " << socket->write(read);
socket->waitForBytesWritten();
read.clear();
}
inputFile.close();
Run Code Online (Sandbox Code Playgroud)
QTcpSocket* socket = static_cast<QTcpSocket*>(sender());
QBuffer* buffer = buffers.value(socket);
QByteArray read = socket->read(socket->bytesAvailable());
qDebug() << "Read : " << read.size();
QFile file( ???); // what should I put in the bracket???
if(!(file.open(QIODevice::Append)))
{
qDebug("File cannot be opened.");
exit(0);
}
file.write(read);
file.close();
Run Code Online (Sandbox Code Playgroud) 我想知道 Qt 对QTcpSocket'sReadyRead信号的实现。它是如何在 Windows 和 Linux 上实现的?使用select(),poll(),epoll(),SIGIO或任何其他方式?如何QTcpSocket知道何时发出ReadyRead信号?
我们有两个Qt应用程序.App1接受来自App2的连接,QTcpServer并将其存储在一个实例中QTcpSocket* tcpSocket.App1运行30 Hz的模拟.对于每次模拟运行,QByteArray使用以下代码(来自主/ GUI线程)发送包含几千字节的数字:
QByteArray block;
/* lines omitted which write data into block */
tcpSocket->write(block, block.size());
tcpSocket->waitForBytesWritten(1);
Run Code Online (Sandbox Code Playgroud)
接收器套接字侦听QTcpSocket :: readDataBlock信号(在主/ GUI线程中)并将相应的时间戳打印到GUI.
当App1和App2在同一系统上运行时,这些包完全同步.但是,当App1和App2在通过网络连接的不同系统上运行时,App2不再与App2中的模拟同步.包裹的速度要慢得多.更令人惊讶的是(并且表明我们的实现是错误的)事实是当我们停止模拟循环时,不再接收到包.这让我们感到惊讶,因为我们期望从TCP协议中最终到达所有包.
我们基于Qt的财富示例构建了TCP逻辑.然而,财富服务器是不同的,因为它每个传入的客户端只发送一个包.有人可以确定我们做错了什么吗?
注意:我们使用MSVC2012(App1),MSVC2010(App2)和Qt 5.2.
编辑:对于一个包我的意思是单个模拟实验的结果,这是一堆数字,写入QByteArray block.但是,第一位包含QByteArray的长度,以便客户端可以检查是否已收到所有数据.这是发出信号QTcpSocket :: readDataBlock时调用的代码:
QDataStream in(tcpSocket);
in.setVersion(QDataStream::Qt_5_2);
if (blockSize == 0) {
if (tcpSocket->bytesAvailable() < (int)sizeof(quint16))
return; // cannot yet read size from data block
in >> blockSize; // read data size for data block
}
// if the whole data block is …Run Code Online (Sandbox Code Playgroud) 我在运行时不断获取应用程序的数据,但是一旦我读完数据并将其存储在地图中,我就会遇到一些问题.
当我尝试在QML中显示数据时,它只显示零,尽管我可以在应用程序输出中看到它更新.
我使用属性绑定访问QML中的值(我的印象是这些导致headingSensor每次carData.headingSensor更改时都会更新?):
property int headingSensor: carData.headingSensor
Text { text: "Heading: " + headingSensor }
Run Code Online (Sandbox Code Playgroud)
在我的数据类中,我有:
Q_PROPERTY(int headingSensor READ getHeadingSensor NOTIFY headingSensorChanged)
int headingSensor;
Run Code Online (Sandbox Code Playgroud)
在我最初的c ++实现中:
int data::getHeadingSensor(){
return data.value(heading)[headingSensorReading];
}
Run Code Online (Sandbox Code Playgroud)
它返回正在使用传入信息更新的地图中的值.
我意识到这可能不起作用,因为该属性依赖于headingSensor变量,尽管返回了正确的值,但该变量本身并未更新.所以,我想如果我更改它以更新headingSensor值并返回它可能会起作用.
所以在我的数据采集逻辑中,我写了一个方法来更新变量.
data.insert(key, value);
updateVariables();
}
}
}
void data::updateVariables(){
headingSensor = data.value(heading)[headingSensorReading];
}
int data::getHeadingSensor(){
return headingSensor;
}
Run Code Online (Sandbox Code Playgroud)
虽然这导致headingSensor除了地图中的值之外更新变量,但QML显示中仍未显示正确的值.它只显示0(最初显示时的默认值,因为它尚未从传入数据中获取值).
所以,我想知道,如何将QML中显示的sensorHeading的值更新为它的值和/或地图中的值在C++中更改?我是否需要做以下事情:
Connections {
target: carData
onSensorHeadingChanged: updateValues
}
Run Code Online (Sandbox Code Playgroud)
编辑:尝试这样的东西,onSensorHeadingChanged永远不会激发.我不知道为什么,因为我在应用程序输出中看到它时,sensorHeading的值明显改变
Connections{
target: carData
onHeadingSensorChanged: console.log("It's noting the change!")
}
Run Code Online (Sandbox Code Playgroud) 请告知如何在不使用阻塞waitForConnected()方法的情况下设置默认连接超时?我注意到套接字在大约60秒后发出错误信号(QAbstractSocket :: SocketTimeoutError),我可以将其作为超时处理,但可以调整此超时吗?
qtcpsocket ×10
qt ×8
c++ ×5
sockets ×4
qtcpserver ×2
qtnetwork ×2
binding ×1
pyqt4 ×1
python ×1
qml ×1
qsslsocket ×1
qt5 ×1
qtquick2 ×1
tcp ×1