Qt-创建写式和只读套接字
我有一只袜子 我需要两个插座。其中一个是只读的,另一个是写的Qt-创建写式和只读套接字,qt,sockets,readonly,writeonly,Qt,Sockets,Readonly,Writeonly,我有一只袜子 我需要两个插座。其中一个是只读的,另一个是写的 不可能吗?如果是这样,怎么办?Qt的套接字不支持每个本机套接字有多个套接字对象,但您可以通过创建适当的单向接口来近似实现这一点 在下面的示例中,接口不执行任何缓冲,因此它们强制每个套接字中每种类型的接口只有一次。一旦使用了接口,就不应该直接使用套接字 // https://github.com/KubaO/stackoverflown/tree/master/questions/socket-split-43409221 #inclu
不可能吗?如果是这样,怎么办?Qt的套接字不支持每个本机套接字有多个套接字对象,但您可以通过创建适当的单向接口来近似实现这一点 在下面的示例中,接口不执行任何缓冲,因此它们强制每个套接字中每种类型的接口只有一次。一旦使用了接口,就不应该直接使用套接字
// https://github.com/KubaO/stackoverflown/tree/master/questions/socket-split-43409221
#include <QtNetwork>
class SocketBase : public QIODevice {
Q_OBJECT
public:
explicit SocketBase(QAbstractSocket * parent) : QIODevice{parent} {
connect(parent, &QAbstractSocket::connected, this, &SocketBase::connected);
connect(parent, &QAbstractSocket::disconnected, this, &SocketBase::disconnected);
connect(parent, &QAbstractSocket::stateChanged, this, [this](QAbstractSocket::SocketState state){
emit stateChanged(state);
setOpenMode(m_dev->openMode());
});
connect(parent,
static_cast<void(QAbstractSocket::*)(QAbstractSocket::SocketError)>(&QAbstractSocket::error),
this, [this](QAbstractSocket::SocketError error){
setErrorString(m_dev->errorString());
emit this->error(error);
});
setOpenMode(m_dev->openMode());
}
QAbstractSocket::SocketError error() const {
return m_dev->error();
}
QAbstractSocket::SocketState state() const {
return m_dev->state();
}
Q_SIGNAL void connected();
Q_SIGNAL void disconnected();
Q_SIGNAL void error(QAbstractSocket::SocketError);
Q_SIGNAL void stateChanged(QAbstractSocket::SocketState);
bool isSequential() const override { return true; }
protected:
QAbstractSocket * const m_dev = static_cast<QAbstractSocket*>(parent());
};
class ReadSocket : public SocketBase {
Q_OBJECT
public:
explicit ReadSocket(QAbstractSocket * parent) : SocketBase(parent) {
for (auto proxy : parent->findChildren<ReadSocket*>())
Q_ASSERT(proxy == this);
connect(m_dev, &QIODevice::readyRead, this, &QIODevice::readyRead);
}
bool atEnd() const override {
return QIODevice::atEnd() && m_dev->atEnd();
}
qint64 bytesAvailable() const override {
return m_dev->bytesAvailable();
}
bool canReadLine() const override {
return m_dev->canReadLine();
}
protected:
qint64 readData(char * data, qint64 maxLength) override {
return m_dev->read(data, maxLength);
}
qint64 readLineData(char *data, qint64 maxLength) override {
return m_dev->readLine(data, maxLength);
}
qint64 writeData(const char *, qint64) override {
return -1;
}
};
class WriteSocket : public SocketBase {
Q_OBJECT
public:
explicit WriteSocket(QAbstractSocket * parent) : SocketBase(parent) {
for (auto proxy : parent->findChildren<WriteSocket*>())
Q_ASSERT(proxy == this);
connect(m_dev, &QIODevice::bytesWritten, this, &QIODevice::bytesWritten);
}
qint64 bytesToWrite() const override {
return m_dev->bytesToWrite();
}
bool flush() {
return m_dev->flush();
}
protected:
qint64 readData(char *, qint64) override {
return -1;
}
qint64 writeData(const char * data, qint64 length) override {
return m_dev->write(data, length);
}
};
int main(int argc, char *argv[])
{
QCoreApplication app{argc, argv};
QHostAddress addr{"127.0.0.1"};
quint16 port{9341};
QTcpServer server;
if (! server.listen(addr, port)) qFatal("can't listen");
QObject::connect(&server, &QTcpServer::newConnection, &server, [&]{
auto s = server.nextPendingConnection();
QObject::connect(s, &QTcpSocket::readyRead, s, [s]{
s->write(s->readAll());
});
QObject::connect(s, &QTcpSocket::disconnected, s, &QObject::deleteLater);
});
const char data_[] = "dhfalksjdfhaklsdhfklasdfs";
auto const data = QByteArray::fromRawData(data_, sizeof(data_));
QTcpSocket client;
WriteSocket writer(&client);
ReadSocket reader(&client);
QObject::connect(&writer, &WriteSocket::connected, [&]{
writer.write(data);
});
QObject::connect(&reader, &ReadSocket::readyRead, [&]{
if (reader.bytesAvailable() >= data.size()) {
auto const read = reader.read(data.size());
Q_ASSERT(read == data);
qApp->quit();
}
});
client.connectToHost(addr, port);
return app.exec();
}
#include "main.moc"
//https://github.com/KubaO/stackoverflown/tree/master/questions/socket-split-43409221
#包括
类SocketBase:公共QIODevice{
Q_对象
公众:
显式SocketBase(QAbstractSocket*parent):QIODevice{parent}{
连接(父级,&QAbstractSocket::connected,this,&SocketBase::connected);
连接(父级,&QAbstractSocket::disconnected,此,&SocketBase::disconnected);
连接(父级,&QAbstractSocket::stateChanged,this,[this](QAbstractSocket::SocketState){
发射状态改变(状态);
setOpenMode(m_dev->openMode());
});
连接(父级,
静态_转换(&QAbstractSocket::error),
此[此](QAbstractSocket::SocketError错误){
setErrorString(m_dev->errorString());
发出此->错误(error);
});
setOpenMode(m_dev->openMode());
}
QAbstractSocket::SocketError错误()常量{
返回m_dev->error();
}
QAbstractSocket::SocketState()常量{
返回m_dev->state();
}
Q_信号无效连接();
Q_信号无效断开();
Q_信号无效错误(QAbstractSocket::SocketError);
Q_信号无效状态已更改(QAbstractSocket::SocketState);
bool isSequential()常量重写{return true;}
受保护的:
QAbstractSocket*const m_dev=static_cast(parent());
};
类ReadSocket:publicsocketbase{
Q_对象
公众:
显式ReadSocket(QAbstractSocket*父级):SocketBase(父级){
对于(自动代理:父->findChildren())
Q_断言(代理==此);
连接(m_dev,&QIODevice::readyRead,this,&QIODevice::readyRead);
}
bool atEnd()常量重写{
返回QIODevice::atEnd()和&m_dev->atEnd();
}
qint64字节可用()常量重写{
返回m_dev->bytesavable();
}
bool canReadLine()常量重写{
返回m_dev->canReadLine();
}
受保护的:
qint64读取数据(字符*数据,qint64最大长度)覆盖{
返回m_dev->read(数据,最大长度);
}
qint64 readLineData(字符*数据,qint64 maxLength)重写{
返回m_dev->readLine(数据,最大长度);
}
qint64写入数据(常量字符*,qint64)重写{
返回-1;
}
};
类WriteSocket:公共SocketBase{
Q_对象
公众:
显式WriteSocket(QAbstractSocket*父级):SocketBase(父级){
对于(自动代理:父->findChildren())
Q_断言(代理==此);
连接(m_dev,&QIODevice::BytesWrited,this,&QIODevice::BytesWrited);
}
qint64 bytesToWrite()常量重写{
返回m_dev->bytesToWrite();
}
bool flush(){
返回m_dev->flush();
}
受保护的:
qint64读取数据(字符*,qint64)覆盖{
返回-1;
}
qint64 writeData(常量字符*数据,qint64长度)重写{
返回m_dev->write(数据,长度);
}
};
int main(int argc,char*argv[])
{
QCoreApplication{argc,argv};
QHostAddress地址{“127.0.0.1”};
第16港{9341};
qtcserver服务器;
如果(!server.listen(addr,port))qFatal(“无法侦听”);
QObject::connect(&server,&QTcpServer::newConnection,&server,[&]{
auto s=server.nextPendingConnection();
QObject::connect(s,&QTcpSocket::readyRead,s,[s]{
s->write(s->readAll());
});
QObject::connect(s,&qtcSocket::disconnected,s,&QObject::deleteLater);
});
const char data_[]=“dhfalksjdfhaklsdhfklasdfs”;
auto const data=QByteArray::fromRawData(数据,大小);
qtcsocket客户端;
WriteSocket编写器(和客户端);
ReadSocket读卡器(和客户端);
QObject::connect(&writer,&WriteSocket::connect,[&]{
writer.write(数据);
});
QObject::connect(&reader,&ReadSocket::readyRead,[&]{
if(reader.bytesavable()>=data.size()){
auto const read=reader.read(data.size());
Q_断言(读取==数据);
qApp->quit();
}
});
client.connectToHost(地址、端口);
返回app.exec();
}
#包括“main.moc”