Pergunta

I've been struggling for a couple of days now with this problem on QTcpSockets and QThreads.

I have a QTcpServer that listens on a port and creates a new Client using the nextPendingConnection(). So now the client has a qtcpsocket which I can use for reading and writing.

Let's suppose I have 100 clients connected to my server. When one of them wants to broadcast a message to everybody, my main thread (where I create the clients with nextPendingConnection() ) will have to iterate over 100 clients and call the write method on their sockets. If for example 10 users broadcast at the same time, I will have to make 1000 iterations, so in my opinion there will be some latency on the client side(when the user receive the messages).

I would like to do all the socket writing in separe threads, so that I can send data in paralel. I know that I can't call a socket from another thread from the one that it was created in and I don't want to use one thread per client because I don't know if it's a good think to have a lot of threads(besides, these threads should be always running unless a client disconnects).

I've read the thread fortune server example, but it doesn't answer my problem because they destroy the socket after sending data; I don't want to destroy my socket because I have to listen on it for the incoming messages(so I can broadcast them).

One thing I thought about is to have 2 sockets for each client(on the server and on the client side); so that I keep one socket for reading, and the other one i can use just like in the thread fortune server example; in this case, i would also use a threadpool to limit the number of tasks (otherwise it would be the same thing as using one thread per client).

Could you please point me in the right direction or give me some hints about how implementing paralel socket writing without actually having one thread per client...?

Best Regards,

Sebastian

Foi útil?

Solução

Have a 'WriteToSocket' function that writes data to a particular socket. Also, have a queue that holds data bound for a socket, protected by a mutex. In the function, add the data you want to send to the queue for the socket. Check if the socket is already assigned to a thread (keep a flag for this purpose). If so, you're done. If not, schedule a job to a thread pool to send the data out the socket.

Depending on a lot of details, you may prefer an alternative implementation. In this implementation, the send logic for each socket has two modes, queued and unqueued. Sockets start unqueued. When you want to send to a socket, acquire the lock that protects it. If it's in queued mode, add the data to the queue and you're done.

If you're in unqueued mode, try to send the data with a non-blocking send. If you send all of it, you're done. Otherwise, save the unsent data to the queue and put the socket in queued mode.

You will need to arrange some mechanism to 'periodically' attempt to send data on the sockets in queued mode. Normally, you would do that with something like 'select' or 'poll'. With QTcpSockets, you have signals and slots.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top