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.