Strategy for 2 way communication with UDPClients - c#

Hi I'm wondering how to set up UDPClients to enable real-time 2 way communication between clients
I'm working on a simple network game in C#, it should be possible for a player to host a game and for others to connect to it
The host will send out the new game state every X millisecond and will simultaneously be receiving a continuous stream of user input from the other players
The other players will constantly be waiting for new input states and also be sending out user input to the host
What I'm wondering is how to achieve this.
Should I be using 2 different UDPClients, isn't there a potential thread conflict if they try to utilize the same resource at the same time? If not, do i need to set them up in some special way, else if I'm using 1 UDPClient, is there anything special i need to account for or is it thread safe and i can just fire away new messages while receiving?

UDP is a duplex protocol (like TCP).
You can safely send and receive off the UDPClient object at the same time. You should not use two UDPClient objects.
However, those operations do occur on separate threads (or pseudo-threads, if you use await/async), so you may run into synchronization issues in the calling code (obviously its hard to say without seeing it, but the potential is there).

Related

Deadlocked when both endpoints do Socket.SendAsync

So I have written this client/server socket application that uses the SocketAsyncEventArgs "method" for doing async sockets.
Using the same library I have used for many other applications, I now for the first time experience a situation that I never anticipated.
Our new client/server application when started, starts to send lot's of data in both directions.
When done in unit-tests using mock-objects (without delays) to mimic normal socket operations, it all works well.
But in real situations using real sockets, we get a sort of deadlock where both endpoints are stuck in a Socket.SendAsync() operation (yes it returned true, was not synchronously handled)
My idea is that the receive buffer of both parties are full, and the tcp stack is not acknowleding any frames anymore. (connected to 127.0.0.1)
So I made the receivebuffer twice as large as the sendbuffer, but unfortunately it is not that simple due to the nature of our "protocol", and how we determine to send or receive.
I now have to re-think the method that determines when to start sending and when to start receiving.
A complicating factor is, that the purpose of this connection is to mutliplex multiple bi-directional general purpose communication channels over this socket connection. That means that there is no pre-determined sequence of communication, all channels may have their own protocols.
Of course, there is a tls initiation, handshake and authentication, which all work well, but when the connection becomes operational, and the channels start their own communications, the only sure thing is that received data has a size and channelnumber as a header.
After each operation, I check to see if there is any waiting data in the receivebuffer, or by checking Socket.Available.
This combined with measuring how much data was received since last sent operation, and how full the transmitbuffer is getting, I decide to receive more or start sending, or do nothing, and poll again in xx ms.
I now realize that this is wronge.
Am I trying to accomplish something that is simply not possible using only one socket connection?
Anyone every tried to accomplish something simular, or know a good way of accomplish a safe way that does not introduce these odd lock-ups.
Thanks,
Theo.

.Net Socket (UDP) Sending, Receiving and Scheduling

I am currently on a personal project for learning purposes. I want to make a connection over UDP, for application such as games. Each datagram sent has a specific header that indicates which "logic" channel it belongs to - for example, channel 0 is just like UDP with the extra header overhead, and channel 1 uses more headers to bring some extra reliability. The channels objective is to "automatically" separate messages into logic groups, up to a specific amount.
In my current code, there is a simple loop in a separate thread that handles sending and receiving:
// This is pseudo code
public void Tick() {
if(Socket.Poll) {
do {
ReadMessage();
} while(Socket.Available > 0)
}
SendQueuedOutgoingMessages();
}
Though this works on an ideal world, I have this feeling that this logic fails when there are too many incoming or outgoing messages. Is it possible to use the same socket to simultaneously send and receive messages (i.e send and receive are asynchronous or in different threads)? Even if it is possible, would it be better if I simply used two or more UDP sockets (or mix TCP and UDP sockets, if I need reliability), having specially maintainability in mind?
The most direct alternative I can think around this would be to use a scheduling algorithm to control how many messages to read and send, by means of queue sizes or other factors, but this feels poor and inflexible in this situation.
Edit: Adding more information about the code.
The Tick() method is set to be called a specific amount of times per second if it immediately returns. For example, 30 times per second if no new in or out messages exists, and less if it needs some time to send or receive data. I've used blocking ReceiveFrom and SendTo methods as to avoid busy waiting or calls such as Sleep(0).
Though I immediately treat incoming messages, I use an outgoing messages queue to help with the channels idea - each channel has its own priority down to 'no priority', affecting its bandwidth share over time in smooth and busy moments.
Whether or not using 2 sockets for receiving and sending separately, or just a single one depends on the situation. If you are going to send a lot of messages, and even if you are on a dedicated thread, the socket might block if the outgoing queue that is used by the socket becomes full.
There are several solutions to this problem. Using 2 sockets and 2 distinct threads is one of them, using select in combination with asynchronous sockets is another. The point is that you don't want to stop receiving just because a send might block.
Each of these possible solutions have their own complexity.
The select api is meant to check if for a certain socket there is something to receive, but you can also use it to detect if a socket becomes writable again. You need a socket option to put the socket in non blocking state and you need to check for E_WOULDBLOCK return codes with each send. If so the send has failed and you have to queue the message yourself.
You don't really send and receive at the same time, it is sequentially. You use select to check if a socket is writable and readible by using 2 bitmasks manipulated with the fd_set api. You can use select even on multiple sockets at once. Then if select, which is a blocking call, returns, you can check each individual bit to check what actions needs to be performed.
The reason why a send can block, if a socket is not put in nonblocking state is that the output queue of the socket can be full. If the socket is blocking, it would simply wait for the queue to become ready again. But during that wait, you cannot receive anything on that same socket. This is the very reason why you need non blocking sockets and the select api, in combination with some kind of queueing mechanism yourself.
Why not simply the standard read loop setup?
while (true)
ReadMessage();
There is no scheduling or throttling necessary. It is not necessary to know whether a packet is ready or not.
You can read and write simultaneously on the same UDP socket.
There is no need for an outgoing queue, either. Just send.

Not lock up the GUI on thread.sleep

I'm writing a multiple user server\client application.
Essentially, it will implement a chat room and allow users to communicate with each other. I've gotten the application to work between the server\client so far by sending a request to the server, which is always checking for an incoming network connection, and responding to it immidiately.
However, for the client to receive chat messages from the server, the only thing I can think of is running a server on the client. If I were to do this, however, the client would freeze up and not be able to do anything. Plus, the client is not designed for opening ports to connect to the server.
What would be the best recommendation on waiting on data from the server to come to the client, without causing the client to lock up?
Thanks!
(and also, I'm not a \professional\ c# programmer, more of an amateur, so please don't give me very complicated answers)
If I were you, I would use either a background worker, or a second thread. If you don't want to do that, you can use thread.suspend.
To start a new thread:
Using System.Threading;
Thread t = new Thread()
t.Start;
Note: this is not recommended.

Voice Conference - how to have more people in conversation?

first of all, I'm just a hobbyist, so I'm sorry if this is dumb question or if I'm being too naive. (It also means that I can't buy expensive libraries)
This is the situation: I'm building a simple voice chat application in C#.NET (something like Ventrilo or TeamSpeak but only for about 15 or 20 people, and running on 100Mbps LAN). I have working server (spawning thread for each client) and client application using UDP for connection and DirectSound for capturing and playing the sound. I can make "1 on 1" calls but I can't figure out one of the most important things:
How do i have more than two people in the conversation?
You need some centralized place to send the packets back out via a multicast, or else you need a decentralized approach where every client is connected to every other client, and each client is hosting a multicast. What you want to avoid is making the machines forward out their data to every other machine, which would result in O(n) time to send a message to each machine (and I/O is slow!).
In either scenario, you end up with the same problem: how to combine the audio streams. One simple mechanism to accomplish this is to bitwise-or the signals together before you send them back out (either out the network port, or out to your speakers), but this assumes you have access to non-compressed and reasonably-synchronized streams.

Single socket multiple clients architecture

I have to maintain a single persistent socket connection to a payment gateway and use it to send financial messages and receive confirmation for the same. My application will be then used by various clients and so I need to devise a way to handle them concurrently and handle issues such as timeouts and retries etc.
Right now, my main issue is with accessing the socket... should I just lock the send and recv per message request and response or set up a queuing system and match them? I'll also be sending periodic echo messages on another thread.
Oh, and I am planning to do it in C#. I would appreciate some general advice on this issue.
You need a persistent socket to the payment gateway, ok. By that I assume you mean it must stay connected.
Then you need to create a listener socket to listen for connections from your clients. Then act as a translator between the two.
I'm not sure I understand what you mean by "lock the socket". Lock it how?
Unless the protocol for the payment gateway is intended for multiple concurrent operations, you probably don't want to send more than one request at a time. This would mean a queue of some sort, or a thread for each request using some kind of mutex or semaphore to control access. A queue is more efficient in most cases.
I did this exact thing (if I understand you correctly). I have a server that connects to some target devices over sockets and then clients hook up to the server to talk to different target systems. Is this (kind of) what you want? I have multiple clients talking to the same socket through the server.
In my server I keep a list of connected clients and a list of connected targets. When a client requests a target I add it to a matrix that is essentially a dictionary of connections because several clients can talk to one target at the same time. The server then pumps messages between clients and targets entirely asynchrounously and I use transaction IDs to keep track of the messages. So that when a target answers a request the server knows to which client to send the answer.
I'm not sure this is what you want but maybe what I did will help you a little on your way anyway. If I'm on the right track I can elaborate further.

Categories

Resources