我对QTcpServer如何在线程和阻塞的幕后工作感兴趣.QTcpServer有一个listen()方法立即返回.如果侦听成功启动,服务器将发出信号newConnection().我感兴趣的是当listen()方法返回时服务器是如何监听的(它是在主线程上).使用QTcpServer的控制台应用程序的常见示例如下所示:
//main.cpp
int main(int argc, char* argv[])
{
QCoreApplication app;
MyServer server;
app.exec();
}
//MyServer.cpp
MyServer::MyServer(QObject *parent) : QObject(parent)
{
this->server = new QTcpServer(this);
connect(server, SIGNAL(newConnection()), this, SLOT(on_newConnection()));
if (!server->listen(QHostAddress::Any, 1234))
//do something in case of error
}
void MyServer::on_newConnection()
{
QTcpSocket* socket = server->nextPendingConnection();
//do some communication...
}
Run Code Online (Sandbox Code Playgroud)
是QTcpServer依赖于QCoreApplication(或者一个QRunLoop)现有和运行recive网络事件.它可以在没有QCoreApplication::exec()被叫的情况下正常工作吗?
我的计算机在本地网络上的IP是192.168.0.100,我启动了我的QTcpServer
if (!tcpServer->listen(QHostAddress::LocalHost, 1234)) {
Run Code Online (Sandbox Code Playgroud)
当我尝试连接到它时netcat 192.168.0.100 1234,连接被拒绝,但netcat localhost 1234成功.
与此同时,如果我倾听netcat -l -p 1234,我可以连接两者192.168.0.100而localhost没有任何问题.
这让我摸不着头脑,为什么会这样?
我在debian wheezy的Qt 5.4.1中使用QSslSocket创建了一个sslclient和sslserver.当我运行程序时,他们根本不工作.在调试我的代码后,我看到它在尝试从中创建一个新对象时,在约束器中QSslSocket返回此错误(cannot resolve SSLV2_client_method).
这是我的代码块:
SSlClient::SSlClient(QObject *parent) : QObject(parent)
{
client = new QSslSocket(this);
client->setProtocol(QSsl::SslV3);
connect(client, SIGNAL(encrypted()), this, SLOT(startTransfer()));
connect(client, SIGNAL(encryptedBytesWritten(qint64)), this, SLOT(byteWritten()));
}
Run Code Online (Sandbox Code Playgroud) 我正在使用Qt使用QTcpServer创建TCP服务器.每次客户端连接到服务器时,我都想知道远程主机的IP地址和端口号.我尝试搜索文档,但找不到有关此主题的任何信息.
我知道应该有办法,我只是无法搞清楚.请帮忙.
我期待使用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) 我在Qt中编写TCP服务器,它将提供大文件.应用逻辑如下:
bytesWritten看起来像:
Streamer.h:
...
private:
QFile *m_file;
char m_readBuffer[64 * 1024];
QTcpSocket *m_socket;
...
Streamer.cpp
...
void Streamer::bytesWritten() {
if (m_socket->bytesToWrite() <= 0) {
const int bytesRead = m_file->read(m_readBuffer, 64 * 1024);
m_socket->write(m_readBuffer, bytesRead);
}
}
...
Run Code Online (Sandbox Code Playgroud)
所以基本上我只是在完全写入所有待处理数据时才写入新数据.我认为这是最不同步的方式.
一切都正常,但是当有很多同时发生的客户时它很慢.
有大约5个客户端 - 我从该服务器下载速度大约1 MB/s(最大的家庭互联网连接)
约有140个客户端 - 下载速度约为100-200 KB/s.
服务器的互联网连接速度为10 Gbps,140个客户端的使用速度约为100 Mbps,因此我不认为这是问题所在.
服务器的内存使用量为140个客户端 - 100 MB的2GB可用
服务器的CPU使用率 - 最大20%
我正在使用端口800.
当端口800上有140个客户端并且通过它的下载速度就像是100-200 KB/s时,我在端口801上运行单独的副本,并且以1 MB/s的速度下载没有问题.
我的猜测是,不知何故,Qt的事件调度(或套接字通知?)太慢,无法处理所有这些事件.
我试过了:
码:
main.cpp:
#include <sched.h>
int startWorker(void …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) 我正在实现一个FTP服务器,它还不支持IPv6(IPv6连接不能使用PORT和PASV,它们需要使用EPRT和EPSV来指定数据连接).
所以我只需要接受来自QTcpServer的IPv4连接.现在我开始用这段代码听:
server->listen(QHostAddress::Any, port);
Run Code Online (Sandbox Code Playgroud)
QHostAddress :: Any应该是IPv4 any-address,但是当我指定localhost而不是127.0.0.1时,Filezilla仍然设法使用IPv6进行连接.我认为QHostAddress :: Any意味着只接受IPv4传入连接,但显然不是这种情况.
那么如何禁用IPv6连接?
我创建了一个QTcpServer端口1024.我想通过使用URL从websocket连接到它ws://localhost:1024,但它没有连接.我们不能将websockets连接到常规TCP服务器套接字吗?
我正在设计一个使用Qt创建者访问远程桌面的应用程序.为了从远程桌面获取"退出"信号(在完成我的目的之后),我使用的是Tcpserver和Tcpsocket.我的Pc充当服务器,而远程PC充当客户端.我使用以下概念:
Server pc 1.按PushButton访问远程屏幕(使用tightvnc以全屏模式).2.启动服务器并侦听任何活动连接(我正在使用端口9876).3.找到活动连接.连接到客户端.4.关闭远程访问.5.切换回本地屏幕.6.服务器关闭
客户端PC 1.按退出按钮关闭远程访问.2.按下退出按钮时3.连接到主机.4.将"退出"发送到服务器5.断开与主机的连接6.关闭连接.
几次尝试都可以正常工作(比方说10次)
但在它开始给出错误"连接拒绝错误"之后.而且我无法从远程访问中恢复,直到重新启动我的远程PC.
我尝试过使用Reset但结果是一样的.
任何人都有任何想法???
这是我的客户端代码
#include "ctrlboardclient.h"
#include <QHostAddress>
#include <QObject>
#include <QtGui/QApplication>
#include <QDebug>
bool CtrlBoardClient::status_flag = false; /* Flag to check the transfer status of Data */
CtrlBoardClient::CtrlBoardClient()
{
connect(&client, SIGNAL(connected()), this, SLOT(startTransfer()));
connect(&client, SIGNAL(readyRead()), this, SLOT(recieve_msg()));
connect(&client, SIGNAL(disconnected()), this, SLOT(disconnectstatus()));
connect(&client, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(getErrorCode(QAbstractSocket::SocketError)));
}
bool CtrlBoardClient::start(QString address, quint16 port)
{
QHostAddress addr(address);
bool rval = client.reset();
qDebug() << "Reset before Connect to Host = " << rval;
client.connectToHost(address, port);
if …Run Code Online (Sandbox Code Playgroud) 使用时如何使用Qtcpsocket发送字符串
tcpsocket->write("hello");
tcpsocket->write("world");
etc..
tcpSocket->flush();
tcpSocket->waitForBytesWritten(3000);
Run Code Online (Sandbox Code Playgroud)
它以一个字符串“hello world”发送它,我想让它一次只写一个,我想让客户端接收“hello”然后是“world”。
我知道如何在发出消息时向新连接的客户端发送消息QTcpServer newConnection。我所做的是这样的:
connect(serverConnection.tcpServer, &QTcpServer::newConnection, this, &ServerInterface::sendMessages);
void ServerInterface::sendMessages()
{
QByteArray messagesToClients;
QDataStream out(&messagesToClients, QIODevice::WriteOnly);
QTcpSocket *clientConnection = serverConnection.tcpServer->nextPendingConnection();
out << inputBox->toPlainText(); //get text from QTextEdit
clientConnection->write(messagesToClients);
}
Run Code Online (Sandbox Code Playgroud)
但是我想要做的是每当在服务器中单击发送消息按钮时,它就会向当前连接的客户端发送消息。我提供的代码只能向新连接的客户端发送一条新消息。我不知道如何实现我想做的事情,所以有人可以为我提供一种方法吗?我是 Qt 网络的新手。
谢谢。
qtcpserver ×12
qt ×11
qtcpsocket ×6
c++ ×5
ip ×1
linux ×1
networking ×1
performance ×1
pyqt4 ×1
python ×1
qsslsocket ×1
qtnetwork ×1
websocket ×1