Is QlocalSocket really used for namedpipes



  • According to Qt documentation if we want to use name pipe in windows we can use Qlocalsocket. I write a server and client program by Qt. The strange is that If I try to use windows proper APIs to write some message in the pipe line-by using win32-, The Qt client does not show it. Also if the client which writes in win32, the QT server does not echo the send message. Does QlocalSocket really used for named pipe?


  • Lifetime Qt Champion

    Hi,

    Could you post a code example that allows to test the behavior ?



  • This is the code for client side written in VC++
    @ wcout << "Connecting to pipe..." << endl;

        // Open the named pipe
        // Most of these parameters aren't very relevant for pipes.
        HANDLE pipe = CreateFile&#40;
            L"\\\\.\\pipe\\ServicePipe",
            GENERIC_READ, // only need read access
            FILE_SHARE_READ | FILE_SHARE_WRITE,
            NULL,
            OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL,
            NULL
            &#41;;
    
        if (pipe == INVALID_HANDLE_VALUE) {
            wcout << "Failed to connect to pipe." << endl;
            // look up error code here using GetLastError()
            system&#40;"pause"&#41;;
            return 1;
        }
    
        wcout << "Reading data from pipe..." << endl;
    
        // The read operation will block until there is data to read
        wchar_t buffer[128];
        DWORD numBytesRead = 0;
        BOOL result = ReadFile&#40;
            pipe,
            buffer, // the data from the pipe will be put here
            127 * sizeof(wchar_t&#41;, // number of bytes allocated
            &numBytesRead, // this will store number of bytes actually read
            NULL // not using overlapped IO
            );
    
        if (result) {
            buffer[numBytesRead / sizeof(wchar_t)] = '?'; // null terminate the string
            wcout << "Number of bytes read: " << numBytesRead << endl;
            wcout << "Message: " << buffer << endl;
        } else {
            wcout << "Failed to read data from the pipe." << endl;
        }
    
        // Close our pipe handle
        CloseHandle(pipe);
    
        wcout << "Done." << endl;@
    

    and this is the code for server side written in VC++
    @ wcout << "Creating an instance of a named pipe..." << endl;

        // Create a pipe to send data
        HANDLE pipe = CreateNamedPipe(
            L"\\\\.\\pipe\\ServicePipe", // name of the pipe
            PIPE_ACCESS_OUTBOUND, // 1-way pipe -- send only
            PIPE_TYPE_BYTE, // send data as a byte stream
            1, // only allow 1 instance of this pipe
            0, // no outbound buffer
            0, // no inbound buffer
            0, // use default wait time
            NULL // use default security attributes
            );
    
        if (pipe == NULL || pipe == INVALID_HANDLE_VALUE) {
            wcout << "Failed to create outbound pipe instance.";
            // look up error code here using GetLastError()
            system&#40;"pause"&#41;;
            return 1;
        }
    
        wcout << "Waiting for a client to connect to the pipe..." << endl;
    
        // This call blocks until a client process connects to the pipe
        BOOL result = ConnectNamedPipe(pipe, NULL);
        if (!result) {
            wcout << "Failed to make connection on named pipe." << endl;
            // look up error code here using GetLastError()
            CloseHandle(pipe); // close the pipe
            system&#40;"pause"&#41;;
            return 1;
        }
    
        wcout << "Sending data to pipe..." << endl;
    
        // This call blocks until a client process reads all the data
        wcout <<endl<<"Input your message: ";
    
        wstring data=L"";
        getline(wcin,data);
        DWORD numBytesWritten = 0;
        result = WriteFile&#40;
            pipe, // handle to our outbound pipe
            data.c_str(&#41;, // data to send
            wcslen(data.c_str()) * sizeof(wchar_t), // length of data to send (bytes)
            &numBytesWritten, // will store actual amount of data sent
            NULL // not using overlapped IO
            );
    
    
        if (result) {
            wcout << "Number of bytes sent: " << numBytesWritten << endl;
        } else {
            wcout << "Failed to send data." << endl;
            // look up error code here using GetLastError()
        }
    
        // Close the pipe (automatically disconnects client too)
        CloseHandle(pipe);
    
        wcout << "Done." << endl;@
    


  • This is the client side written in QT
    @LocalSocketIpcClient::LocalSocketIpcClient(QString remoteServername, QObject *parent) :
    QObject(parent) {

    m_socket = new QLocalSocket(this);
    m_serverName = remoteServername;
    
    connect(m_socket, SIGNAL(connected()), this, SLOT(socket_connected()));
    connect(m_socket, SIGNAL(disconnected()), this, SLOT(socket_disconnected()));
    
    connect(m_socket, SIGNAL(readyRead()), this, SLOT(socket_readReady()));
    connect(m_socket, SIGNAL(error(QLocalSocket::LocalSocketError)),
            this, SLOT(socket_error(QLocalSocket::LocalSocketError)));
    

    }

    LocalSocketIpcClient::~LocalSocketIpcClient() {
    m_socket->abort();
    delete m_socket;
    m_socket = NULL;
    }

    QString LocalSocketIpcClient::Read()
    {

    QDataStream in(this->m_socket);
    in.setVersion(QDataStream::Qt_5_1);
    
    if (m_socket->bytesAvailable() < (int)sizeof(quint16)) {
        return "No data available";
    }
    
    QString message;
    in >> message;
    return message;
    

    }

    void LocalSocketIpcClient::send_MessageToServer(QString message) {
    m_socket->abort();
    m_message = message;
    m_socket->connectToServer(m_serverName,QIODevice::ReadWrite);
    }

    void LocalSocketIpcClient::socket_connected(){
    QByteArray block;
    QDataStream out(&block, QIODevice::ReadWrite);
    out.setVersion(QDataStream::Qt_5_1);
    out << m_message;
    out.device()->seek(0);
    m_socket->write(block);
    m_socket->flush();
    }

    void LocalSocketIpcClient::socket_disconnected() {
    //showMessage("Client socket_disconnected");
    }

    void LocalSocketIpcClient::socket_readReady() {
    //showMessage("Client socket read Ready");

    QDataStream in(this->m_socket);
    in.setVersion(QDataStream::Qt_5_1);

    if (m_socket->bytesAvailable() < (int)sizeof(quint16)) {
    return;
    }

    QString message;
    in >> message;
    emit RecievedDataFromServer(message);

    }

    void LocalSocketIpcClient::socket_error(QLocalSocket::LocalSocketError e) {
    /*
    QString errorMessage="Client socket_error:";

    switch (e) {
    case QLocalSocket::ConnectionRefusedError:
        errorMessage+="The connection was refused by the peer (or timed out).";
        break;
    
    case QLocalSocket::PeerClosedError:
        errorMessage+="The remote socket closed the connection. Note that the client socket (i.e., this socket) will be closed after the remote close notification has been sent.";
        break;
    
    case QLocalSocket::ServerNotFoundError:
        errorMessage+="The local socket name was not found.";
        break;
    
    case QLocalSocket::SocketAccessError:
        errorMessage+="The socket operation failed because the application lacked the required privileges.";
        break;
    
    case QLocalSocket::SocketResourceError:
        errorMessage+="The local system ran out of resources (e.g., too many sockets).";
        break;
    
    case QLocalSocket::SocketTimeoutError:
        errorMessage+="The socket operation timed out.";
        break;
    
    case QLocalSocket::DatagramTooLargeError:
        errorMessage+="The datagram was larger than the operating system's limit (which can be as low as 8192 bytes).";
        break;
    
    case QLocalSocket::ConnectionError:
        errorMessage+="An error occurred with the connection.";
        break;
    
    case QLocalSocket::UnsupportedSocketOperationError:
        errorMessage+="The requested socket operation is not supported by the local operating system.";
        break;
    
    case QLocalSocket::UnknownSocketError:
        errorMessage+="An unidentified error occurred.";
        break;
    
    default:
        break;
    }
    showMessage(errorMessage);
    

    */
    }

    void LocalSocketIpcClient::showMessage(QString msg)
    {
    QMessageBox m;
    m.setText(msg);
    m.exec();
    }

    //The following line is used for using it in a simple form which contains just a button,text edit and line edit

    FrmMain::FrmMain(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::FrmMain)
    {
    ui->setupUi(this);

    m_client = new LocalSocketIpcClient("\\\\.\\pipe\ServicePipe", this);
    connect(ui->pushButtonSend, SIGNAL(clicked()), this, SLOT(send_button_clicked()));
    connect(this->m_client,SIGNAL(RecievedDataFromServer(QString)),this,SLOT(UpdateGUI(QString)));
    connect(this->ui->pushButtonSend,SIGNAL(clicked()),this,SLOT(send_button_clicked()));
    QTime time = QTime::currentTime();
    qsrand((uint)time.msec());
    
    ui->lineEdit->setText("Client "+QString::number(qrand()));
    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(setLabel()));
    timer->start(1000);
    
    this->counter=0;
    

    }

    FrmMain::~FrmMain()
    {
    timer->disconnect();
    delete timer;
    m_client->disconnect();
    delete m_client;
    delete ui;
    }

    void FrmMain::send_button_clicked()
    {//This function tries to read data from server
    /*
    QDateTime localDateTime = QDateTime::currentDateTime();
    QString timeString = "\\.\pipe\InterfacePipe: " + localDateTime.toString("hh:mm:ss AP dd/MM/yyyy");
    timeString+="\n"+ui->textEdit->toPlainText();
    m_client->send_MessageToServer(timeString);
    */
    QMessageBox m;
    m.setText(m_client->Read());
    m.exec();
    }

    void FrmMain::setLabel()
    {
    this->counter++;
    this->ui->label->setText(QString::number(this->counter));

    QDateTime localDateTime = QDateTime::currentDateTime();
    QString timeString = localDateTime.toString("hh:mm:ss AP dd/MM/yyyy");
    timeString+=" "+ui->lineEdit->text()+" "+QString::number(this->counter);
    m_client->send_MessageToServer(timeString);
    

    }

    void FrmMain::UpdateGUI(QString message){
    ui->textEdit->insertPlainText(message+"\n");
    }

    @



  • The following code is the server side written in QT
    @
    LocalSocketIpcServer::LocalSocketIpcServer(QString servername, QObject *parent)
    :QObject(parent) {
    m_server = new QLocalServer(this);
    if (!m_server->listen(servername)) {
    showMessage("Not able to start the Server");
    }

    connect(m_server, SIGNAL(newConnection()), this, SLOT(socket_new_connection()));
    

    }

    LocalSocketIpcServer::~LocalSocketIpcServer() {

    }

    void LocalSocketIpcServer::socket_new_connection() {

    QLocalSocket *clientConnection = m_server->nextPendingConnection();
    
    while (clientConnection->bytesAvailable() < (int)sizeof(quint32))
        clientConnection->waitForReadyRead();
    
    
    
    //connect(clientConnection,SIGNAL(readyRead()),clientConnection,SLOT(rea));
    connect(clientConnection, SIGNAL(disconnected()),clientConnection, SLOT(deleteLater()));
    
    QDataStream in(clientConnection);
    in.setVersion(QDataStream::Qt_5_1);
    if (clientConnection->bytesAvailable() < (int)sizeof(quint16)) {
        return;
    }
    
    QString message;
    in >> message;
    
    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);
    QString msg=+"Message recieved with content "+message+"\n";
    out.setVersion(QDataStream::Qt_5_1);
    out <<msg;
    out.device()->seek(0);
    clientConnection->write(block);
    clientConnection->flush();
    clientConnection->disconnectFromServer();
    
    emit messageReceived(message);
    

    }

    void LocalSocketIpcServer::showMessage(QString msg)
    {
    QMessageBox m;
    m.setText(msg);
    m.exec();
    }
    //The following lines uses the server side in a form
    FrmMain::FrmMain(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::FrmMain)
    {
    ui->setupUi(this);

    m_server = new LocalSocketIpcServer("\\\\.\\pipe\ServicePipe", this);
    connect(m_server, SIGNAL(messageReceived(QString)), this, SLOT(messageReceived(QString)));
    

    }

    FrmMain::~FrmMain()
    {
    delete ui;
    }

    void FrmMain::messageReceived(QString message)
    {
    ui->textBrowser->append(message+"\n");
    }
    @

    If we run client and server side in MFC or QT, we can see that the message passed correctly, but when we run VC++ client with QT server or QT client with VC++ server no message passed. what's wrong


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.