How do I make sure WinSock sends to all clients? - sockets

I have written a vb6 game to allow 4 players to play a card game.
One of the players will host the game and the others will join.
I used a socket array to join all of the other players with the host socket
Everything went smooth and I am able to send messages from each player to the rest of the players, from host to guests and vice versa
However, during the game, one player would "tell" the host that a card is chosen. The host will then send the same message to each of the clients connected to the socket array like this
For i=1 to 3
Me.SocketArray(i).SendData player.selectedCard
DoEvents
Next
but for some reason, one of the player never receives the message. Although the same player did receive messages before this point, and possible will receive other messages later.
So there is a Syncing problem with what was send and what was not.
I looked for answers everywhere, and some suggested to use DoEvents more often to force the winsock to send the data immediately.
I then thought of implementing an inbox for each player in which each player must reply with an acknowledgment of the received message, and the host will not send any more messages until the arrival of acknowledgement, but that made the game slower and I had the same problem I had before, but this time it's not the messages that got lost, it's the acknowledgment.
The number 1 reason I think I am having all of this is that the Winsock control sometimes sends incomplete messages (one character missing) and that will create a mess, because I need every character at the other end, otherwise the message is useless.
How can I make sure that whenever the host sends a message, all the other guests receive ALL of it intact?

DoEvents() calls are hazardous in the wrong hands.
What you probably have going on is the assumption of "magic" message framing, a failure to buffer and parse messages from inbound data streams, and reentrant calls to your DataArrival handler because you are calling DoEvents().
Nagle could be an issue as well but it should result in responsiveness problems and not apparent data loss.
This same issue has been asked about and answered innumerable times over the last decade.

Related

How to ensure RPC was sent successfully in Photon Unity?

I am building a multiplayer game using Photon and Unity3D engine.
I am using photonView.RPC to send data and values between clients. But sometimes due to network problem, a sent RPC failed to execute in the clients.
Is there any way that I can check from the client (who sent the RPC) that the RPC was sent successfully, if not, then again sent the RPC?
Conceptually, the one and only way you can do that is,
A sends the message, with a identity code (say, "321321777")
A waits for confirmation...
B receives the messsage
B sends a message "I received 321321777"
That's really all you can do. Note that this introduces the concept of a time-out. The above actually goes more like this...
A sends the message, with a identity code (say, "321321777")
A waits for confirmation...
If no confirmation after (say) 0.5 seconds, send it again. Keep doing that.
B receives the messsage. The label is 321321777
B sends a message "I received 321321777"
Any more copies of "321321777" received by B, B ignores it. But: if multiple "321321777" received by B, B does again send more and more confirmation messages for "321321777"
It's worth noting that as a general rule, "video games don't work like this." Normally you just send zillions of positions (or whatever) a second, and if a few are missed - it doesn't matter.
Don't forget too that Unity network DOES "reliable sending" for you anyways - and there's probably such a concept in "PUN".

Is it possible to get POE::Component::IRC to receive events for its own PRIVMSGs?

I'm currently developing a bot with POE::Component::IRC whose job, amongst other things, is to post a notice to a list of channels on a schedule, for one week.
I can't seem to find a way to check that the message has been successfully sent to a channel though. The old Net::IRC package would fire a message received event for every message sent to a channel, including ones it itself had sent. POE seems not to do this - at least, the irc_public event is not firing when the bot's own message is published on the channel.
Is there a flag I can pass to the event handler to say "I'd really like to receive all messages please, even my own"? Or is there a way to do this with some sort of RAW event handler?
The IRC protocol does not echo your PRIVMSGs back to you, so you just have to trust that the server received your message and handled it the way it should.
If you just want to receive POE events for messages you send, there's a plug-in for that: POE::Component::IRC::Plugin::BotTraffic. It doesn't actually do anything to verify that the messages ever reach the server, though.
Fortunately, IRC runs on top of TCP, which provides guaranteed in-order delivery. Thus, as long as the connection doesn't drop or hang indefinitely, you can pretty safely assume that your commands will reach the server.
If you wanted to be absolutely sure, you could always follow your PRIVMSG with some command, such as TIME or PING, that you know the server will reply to; if it does, you'll know that it received your PRIVMSG too. Of course, even then there's still no guarantee that the server actually passed the message on to the intended recipient(s); things like netsplits do occur from time to time, and can cause messages to be dropped.

Game server TCP networking sockets - fairness

I'm writing a game server for a turn-based game. One criteria is that the game needs to be as fair for all players as possible.
So far it works like this:
Each client has a TCP connection. (If relevant, the connection is opened via WebSockets)
While running, continually check for incoming socket messages via epoll.
Iterate through clients with sockets ready to read:
Read all messages from the client.
Update the internal game state for each message.
Queue outgoing messages to affected clients.
At the end of each "window" (turn):
Iterate through clients and write all queued outgoing messages to their sockets
My concern for fairness raises the following questions:
Does it matter in which order I send messages to the clients?
Calling write() on all the sockets takes only a fraction of a second for my program, but somewhere in the underlying OS or networking would it make a difference if I sorted the client list?
Perhaps I should be sending to the highest-latency clients first?
Does it matter how I write the outgoing messages to the sockets?
Currently I'm writing them as one large chunk. The size can exceed a single packet.
Would it be faster for the client to begin its processing if I sent messages in smaller chunks than 1 packet?
Would it be better to write 1 packet worth to each client at a time, and iterate over the clients multiple times?
Are there any linux/networking configurations that would bear impact here?
Thanks in advance for your feedback and tips.
Does it matter in which order I send messages to the clients?
Yes, by fractions of milliseconds. If the network interface is available for sending the OS will immediately start sending. Why would it wait?
Perhaps I should be sending to the highest-latency clients first?
I think you should be sending in random order. Shuffle the list prior to sending. This makes it fair. I think your question is valid and this should be addressed.
Currently I'm writing them as one large chunk. [...]
First, realize that TCP is stream-based and that there are no packets/messages at the protocol level. On a physical level data is indeed packetized.
It is not necessary to manually split off packets because clients will read data as it arrives anyway. If a client issues a read, that read will complete immediately once the first packet has arrived. There is no artificial waiting in the OS.
Are there any linux/networking configurations that would bear impact here?
I don't know. Be sure to disable nagling.

what are the possible UDP data transfer errors?

we're going to develop a game with internet multiplayer support. since it's an interactive game I know I have to use UDP to reduce connection latency, but I'm wondering what are the possible errors that may occur in a package delivered using UDP connection? everywhere I looked they say UDP provides "Best effort delivery", but no one does give a complete explanation what does it mean. after reading some article there are two questions that I still have:
Is it possible to send a package and receive part of it at the other end of connection?
if your answer to first quesiton is true what would happen to the next packages? should I wait for the rest of package or can I assume next package start with my next recv call?
for our game I think we will need to send 4 packages of around 20 byte each second.
The most common thing that can happen is: one side sends a message, the other receives nothing.
Is it possible to send a package and receive part of it at the other
end of connection?
Not really, not even when the message is huge and it gets fragmented. Unlike in TCP, in UDP every message is independent. You either get it entirely or nothing at all.
So what you should do it just recvfrom things in a loop and process them. Obviously you should make your application impervious to message loss such that a missing message doesn't crash it.

Ensuring send() data delivered

Is there any way of checking if data sent using winsock's send() or WSASend() are really delivered to destination?
I'm writing an application talking with third party server, which sometimes goes down after working for some time, and need to be sure if messages sent to that server are delivered or not. The problem is sometimes calling send() finishes without error, even if server is already down, and only next send() finishes with error - so I have no idea if previous message was delivered or not.
I suppose on TCP layer there is information if certain (or all) packets sent were acked or not, but it is not available using socket interface (or I cannot find a way).
Worst of all, I cannot change the code of the server, so I can't get any delivery confirmation messages.
I'm sorry, but given what you're trying to achieve, you should realise that even if the TCP stack COULD give you an indication that a particular set of bytes has been ACK'd by the remote TCP stack it wouldn't actually mean anything different to what you know at the moment.
The problem is that unless you have an application level ACK from the remote application which is only sent once the remote application has actioned the data that you have sent to it then you will never know for sure if the data has been received by the remote application.
'but I can assume its close enough'
is just delusional. You may as well make that assumption if your send completes as it's about as valid.
The issue is that even if the TCP stack could tell you that the remote stack had ACK'd the data (1) that's not the same thing as the remote application receiving the data (2) and that is not the same thing as the remote application actually USING the data (3).
Given that the remote application COULD crash at any point, 1, 2 OR 3 the only worthwhile indication that the data has arrived is one that is sent by the remote application after it has used the data for the intended purpose.
Everything else is just wishful thinking.
Not from the return to send(). All send() says is that the data was pushed into the send buffer. Connected socket streams are not guarenteed to send all the data, just that the data will be in order. So you can't assume that your send() will be done in a single packet or if it will ever occur due to network delay or interruption.
If you need a full acknowledgement, you'll have to look at higher application level acks (server sending back a formatted ack message, not just packet ACKs).