I'm working with QT UDP Sockets. This Socket are part of a "communication" class called, say, Com. It happens, for the needs of my application, that Com need to be deleted. Now, my question is: is it sufficient to invoke delete myUdpSocket; or should I explicitly invoke flush(), 'close()` or whatever? I ask this because when I delete Com the application does not necessairly need to close but instead it it possible that a new Instance of om need to be instantiated and with that a new instance of a UDP Socket on the same port and at the same addresses.
Yes, deleting the QUdpSocket will close it (and unbind) automatically.
This means that you can create a new instance later on the same port and address.
Related
If I have a pre-existing open file descriptor, referring to an already bound and listening socket, how can I use it to initialize a thrift server object (the non-blocking server preferably) and start accepting RPC requests? The various ThriftSocket objects I've seen only accept address/port (or just port) arguments to create a socket themselves.
For the client side, you have a constructor to construct a socket from a file descriptor:
/**
* Constructor to create socket from file descriptor.
*/
TSocket(THRIFT_SOCKET socket, std::shared_ptr<TConfiguration> config = nullptr);
On Unix system, you can find out that THRIFT_SOCKET is an int, just feed your descriptor here!
Unfortunately, this is not the case for the server side. Inheriting TServerSocket won't solve your issue because the internal socket member is private.
However, the thrift servers all take a TServerTransport as argument. Thus, the idea is to inherit TServerTransport to create a custom TServerSocket. The original TServerSocket can be of help here.
But, the fact they did not add the possibility for this feature might mean it is not safe to do so. You'll have no other choice that inspecting TServerSocket.cpp to check the internal implementation.
I have some devices attached to the same network. All of them runs a TCP server. I have my PC also connected to the same network. I need to collect data from the other devices. So I'm about to write an app in Qt framework which does that. I will exchange small packets with the devices, so I thought I make a generic object for devices which has a QTcpSocket member, and I use signals and slots for receiving data. I have an other class which I use to connect to devices. It inherits QObject and QRunnable. the QRunnables's run method implements the connecting procedure and it looks like this:
QTcpSocket socket;
socket.connectToHost(this->hostAddress, this->portNumber);
if(socket.waitForConnected())
{
emit Connected(this->deviceId, socket.socketDescriptor());
}
else
{
emit Error(this->deviceId);
}
This function is run in a separate thread using QThreadPool to avoid long delay due to connecting time:
Connector* connector = new Connector(hostAddress, port, id);
connect(connector, &Connector::Connected, this, &CommunicationLayer::Connected);
connect(connector, &Connector::Error, this, &CommunicationLayer::Error);
QThreadPool::globalInstance()->start(connector);
And when the Connected signal is fired, I instantiate a device object for that specific id:
this->devices.push_back(new Device(id, socketDescriptor, this));
connect(this->devices.back(), &Device::DataReceived, this, &CommunicationLayer::DataReceived);
The socket's descriptor is passed as an argument and then when the Device object is instantiated, and I call QTcpSocket::setSocketDescriptor on the socket inside the device object with that argument.
My problem is that sometimes I got strange messages:
QSocketNotifier: Invalid socket 7 and type 'Read', disabling...
QSocketNotifier: Invalid socket 7 and type 'Write', disabling...
Sometimes I don't get anything and it just works, sometimes I get both, sometimes just one of them. I am a bit clueless.
Edit:
I think I found what's a problem: because I'm declaring the socket in the run function as an auto variable, it goes out of scope as the function returns, so the socket descriptor is invalid. And because it's running in a separate thread sometimes my device is constructed before the function returns and this way the socket descriptor remains valid. I made the socket object in run function a pointer, it works now, but I don't know if it could cause a memory leak. Any ideas? (If I use a smart pointer to manage the socket's lifetime, I get the same result as before with the auto variable)
When I use CAsyncSocket, can I reuse the same object for another connection (by closing and opening again), or should I create a brand-new object for each connection?
The socket can be reused but it often takes a couple of minutes before it will work. So you should create a new object for each connection.
I have an out of process ATL COM server (exe). When it is started by a Client the server spawns a worker thread which polls for some data. Every time the data is updated I want to notify all of the clients with the updated value.
I have created a COM Client, which connects via CoCreateInstanceEx, creates its Sink object, gets the connection point and calls Advise, all without error. However, When the server tries to Fire_event, it's IConnectionPointImpl::m_vec is empty and no clients are ever notified.
I assume this is because the server creates its own object, so I end up with two instances of IConnectionPointImpl::m_vec, one from the server and one from the client when it calls Advise. How can I get the server data to the clients?
I'd recommend this approach. Create a plain vanilla C++ singleton (not a COM object) - let's call it S. S would hold a list of weak, non-AddRef'ed references to all outstanding COM objects (a C++ class pointer, rather than a COM interface pointer, would be convenient). Your COM objects would register themselves with S in their constructor, and deregister in destructor.
When something interesting happens, your worker thread would notify (call a method on) S, which would notify all registered COM objects, which would call Fire_event on themselves.
Be careful when firing events from a worker thread. This is illegal, unless both your main thread and worker thread enter MTA. See http://vcfaq.mvps.org/com/1.htm for details and some workarounds.
I have a server application with such structure:
There is one object, call him Server, that in endless cycle listens and accepts connections.
I have descendant class from CAsyncSocket, that has overriden event OnReceive, call him ProxySocket.
Also I have a thread pool with early created threads.
When connection is received by server object he accepts the new connection on the new object ProxySocket.
When data arrives to the ProxySocket, he creates a command object and gives it to thread pool. In this command object I giving the socket handle of a ProxySocket. When new object of command is creating - I creating a new Socket in working thread and attach handle to it.
My issue is next:
When command ends, socket doesn't close, I just detach handle it and set CSocket handle to INVALID_SOCKET value, as planned. But my first ProxySocket object doesn't receives messages of new data receiving after that. How can I solve this?
I don't think you can use CAsyncSocket objects (or their descendants) in a thread pool secenario. CAsyncSockets are implemented on top of WSASsyncSelect - which tells the winsock to send notifcations to a window handle.
Because windows have thread affinity, one can never "move" the CAsyncSocket handling to a different thread.