简体   繁体   中英

Named pipe unknown error - Python to Qt C++

I am trying to communicate between Qt 5.4 C++ and Python 2.7 by way of a named pipe. I have it partially working, but there is some incompatibility I'm encountering.

On the Qt side, I have a QLocalServer object:

QLocalServer *localServer_;

After I instantiate, I starting listening on the pipe and connect the signal/slot for newConnection

if( localServer_->listen( settings_.localMessagePipeName() ) )
        connect( localServer_, SIGNAL( newConnection() ),
                 this,           SLOT( newServerConnection() ), Qt::DirectConnection );
    else
        qDebug() << "server listen error!";

My connection handler looks like this:

void newServerConnection()
{
    qDebug() << "pipeConnected";
    QLocalSocket *clientConnection = localServer_->nextPendingConnection();
    connect( clientConnection, SIGNAL( disconnected() ),
             clientConnection,   SLOT( deleteLater() ) );

    qDebug() << clientConnection->error();

    qDebug() << clientConnection->readAll();

    clientConnection->write( "TEST" );
    clientConnection->flush();
    clientConnection->disconnectFromServer();
}

In Python, I send a message down the pipe like this:

response = win32pipe.CallNamedPipe( pipeName, request, 512, 0 )

My Qt connection handler fires off. Data is definitely coming down the pipe. But, here's where it falls apart. This is the output I get in Qt:

pipeConnected
QLocalSocket::UnknownSocketError
""

Note that empty string should have my random testing request value I sent from Python.

On the python end I get this result:

    response = win32pipe.CallNamedPipe( pipeName, request, 512, 0 )
pywintypes.error: (87, 'CallNamedPipe', 'The parameter is incorrect.')

I read a similar thread which said that python error is produced when the other side of the pipe is not created with PIPE_TYPE_MESSAGE. In Qt, it is though. It doesn't seem like that is my problem. Check this Qt source for QLocalServer : https://github.com/radekp/qt/blob/master/src/network/socket/qlocalserver_win.cpp

listener.handle = CreateNamedPipe(
                 (const wchar_t *)fullServerName.utf16(), // pipe name
                 PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,       // read/write access
                 PIPE_TYPE_MESSAGE |       // message type pipe
                 PIPE_READMODE_MESSAGE |   // message-read mode
                 PIPE_WAIT,                // blocking mode
                 PIPE_UNLIMITED_INSTANCES, // max. instances
                 BUFSIZE,                  // output buffer size
                 BUFSIZE,                  // input buffer size
                 3000,                     // client time-out
                 NULL);

BUFSIZE is defined as 0 btw.

In Python, my test client works when I create a pipe in another Python class like this:

def __createPipe( self ):
        pipeName        = getPipeName( self._svc_name_ )
        openMode        = win32pipe.PIPE_ACCESS_DUPLEX | win32file.FILE_FLAG_OVERLAPPED
        pipeMode        = win32pipe.PIPE_TYPE_MESSAGE
        nMaxInstances   = win32pipe.PIPE_UNLIMITED_INSTANCES
        nOutBufferSize  = 0 # use default size
        nInBufferSize   = 0 # use default size
        nDefaultTimeOut = (PIPE_TIMEOUT_SECONDS * 1000) # max time for pipe i/o
        securityAttribs = pywintypes.SECURITY_ATTRIBUTES()      
        securityAttribs.SetSecurityDescriptorDacl( 1, None, 0 ) # full access
        self.pipeHandle_ = win32pipe.CreateNamedPipe( 
            pipeName, openMode, pipeMode,
            nMaxInstances, nOutBufferSize, nInBufferSize,  
            nDefaultTimeOut, securityAttribs )

It seems like those pipes have the same core settings. What am I missing?

Well, I solved my problem in another way. I simply reversed my client/server logic!

I created a pipe server in Python and used QLocalSocket on the Qt end to send and receive messages as a pipe client. That all worked right out of the gate for me. The drawback was having to write a whole lot more code.

In my use case, it actually makes more sense this way, but the first way would have taken a fraction of the lines to implement (at least in Python, it's about the same in Qt). Note that my Python side included the create pipe code I posted in my question as a sample of what worked as a server to my python client that failed with the Qt server. I didn't do anything special with QLocalSocket, it's default properties worked fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM