C++ multi chat server - c++

I am trying to write a multi chat server without using threads. I came across select() but I am having hard time understanding how can I read a client request and send it right away when the send() blocks and the client socket might not be ready to be written and by this losing the server parallel io ability.
If(fd_isset(socket,&read_fds){
Recv()
SendMesgToRequestedClient()
}
I thought a possible solution is to save each client a list of pending messages and send them on fd_isset(socket,&write_fds) but then instead of saving CPU I might use a ton of memory.

Related

Best way to implement handling of read timeouts of socket connections in asynchronous way using C++ and standard C library

There are thousands of clients hitting my server (A) over TCP/IP, I then need to modify the data received and send it across to another server (B), and then get the response and send it back to the client, or handle read timeouts.
Right now a worker thread at server A picks the data from socket send the data to server B over TCP/IP, and in case the server B is slow my server's threads are stuck waiting. Its completely synchronous.
In short I want to implement asynchronous handling of read timeouts or socket read. So the threads can go back to pool after sending data to server B, and in case server B becomes slow server A is still serving requests.
I understand we can achieve using poll, select system calls, but what should be the best way/practice to achieve it. (I cannot use boost)
You need to use non-blocking sockets with an event loop library, such as boost::asio, libevent, libuv. Or, reinvent your own wheel.

socket data emiter c++

i'm having some sync trouble with threads and sockets. I need one thread to recive incoming connections on socket (and remember client data to respond) and other thread to setup frames and send current frame to listed clients. So i was wondering if its possible to (kinda) put my data frames into server socket, so that everyone could just read current frame from socket without server knowing.
Server will just spam its socket with some data and client will get data without server actions. Is this possible? how?
I'm currently doing it pretty messed up way which i dont like:
server is listening on one thread for incoming transmissions and upon reciving such, add client data to list.
on other thread server is sending data to all clients from list.
EDIT:
I want to send data to some kind of buffer from which clients are allowed to read. (client doesnt have to read all messages server sends, just the one buffer contains at the moment of clients request), i dont want server to even notice that clients are reading from buffer if possible.
Right now threads are syncronised using uniqe_lock
What you're describing is probably MultiCast. Specifically, IP MultiCast (I think).
Searching finds a number of useful resources. This one looks concise, and includes coded examples (although I'm not sure how current it is).
If you're only transmitting to a LAN then broadcast will work too.

UDP Server stop receiving data

I am trying to make a online simple game, when I test my game on localhost , there is no problem with the server and the client but when I try to connect my pc to my laptop over local network this start receiving data but few seconds after it stopped.
here is my code:
Server
Client
Your problem probably is that UDP is unreliable, and that sockets by default are blocking.
So think about this situation:
Server is blocked in recvfrom waiting for a packet from the client
The client sends a packet, which is dropped and never reaches the server
The client goes on to it's own recvfrom call which blocks.
Now you have a deadlock as both the server and the client are blocked in recvfrom.
For a simple game like yours you might not need reliability, so it's okay if a packet here or there doesn't arrive. But what is important is that you don't block as then the deadlock situation might occur.
There are basically two solutions to this: The first is to make the sockets non-blocking, and handle the case where recvfrom doesn't receive anything. Take care here though, as your threads doesn't do any sleeping they will consume quite a lot of CPU power.
The second solution is to use polling like e.g. select to see when you can read from the socket.

Reusing an Asio connection

I am working on a project currently where I have a web-server. I have to add the ability so that for each request, I need to send multiple requests to other servers, get responses, and send back results to the original client. These servers are high throughput, so I was getting worried about the number of sockets as well as the speeds of setting up new threads/sockets for sending out many requests over many sockets. So I started thinking that have a single(or a few connections), open to each client would help solve this problem. I wasn't sure how persistent connections and boost ASIO worked though. Some questions I had:
-How can I set keep alive times using ASIO tcp sockets.
-Can I send out multiple concurrent requests over the same socket? Would I run into an issue with the order of the results(Each result should have an Id, so I don't mean order as in results being sent out of order, but more packet order, if a response is more than one packet, will I have a problem with the order of the packets).
All requests are HTTP GET/POST requests if that matters too.
Any information in this subject would be appreciated. Thanks.
A TCP socket acts as a data stream, the data you write on one end will be received in the same order in the other end. You can send multiple requests over the same socket if your protocol can handle it.
You mention concurrent requests, therefore you need to be very careful to not interleave the write calls of two different requests. If you can ensure that each result is written atomically, then I see no problem in using a socket for multiple requests (you can do that with a reply queue).
You can set the standard socket keep alive here.

how synchronize recv() when multithreading cpp CRT

I have a server interacting with multiple clients where the client send messages to the server and the server reads them via recv() method. The problem I getting is that Im using waitforsingleobject(handler, 10000 millisecs) in order to make the server wait for a few seconds to interact with one client and then let others access to it but then I start seeing answer from the server with the wrong message to the client and getting blocked. So looks like a synchronization issue.
So my question is (since I'm a begginer in c++) how could I ensure that every incoming message is received and replied to the right client, allowing all the clients interact with the server.
There're two alternatives.
First is a pretty standard model - one thread per one client. When a client connects, you start a thread to handle it.
Second approach doesn't require many threads. You should use WSARecv() on an overlapped socket instead of recv(). This way, you can simultaneously open multiple receive operations, one per client, and wait them all in a WaitForMultipleObjects(). To be specific, you will wait on event inside WSAOVERLAPPED. Remember that WaitForMultipleObjects() has a limit on number of wait objects. When exceeded, you will need to run another thread. The return code from WaitForMultipleObjects() will tell you which client has sent data, so you can reply to it.
Or, as suggested above, you could probably use select() to figure out which socket has data.