Is UDP viable for trading Server and Clients?

Emon Haque 3,176 Reputation points
2020-11-12T10:59:49.017+00:00

I've experimented once on UDP (Unicast, Multicast and Broadcast) and undermined it always as I read a lot about its unreliability in data transmission. Today, I've read an article, UDP Delivers BUT I'm not sure whether it's suitable for this, my first experimental app with MVVM, type of application. On that, I'd two type of Clients: Ordinary which has the ability to submit, modify and delete an order and Special with an additional ability to send news to the Server. Server handles both Orders and News and eventually broadcasts (in a Parallel.ForEach) those to all connected Clients. I've used TCP in that.

Now, with UDP, I've 3 things: a Trade Server, Server, which receives only orders and broadcasts processed order, a News Server, Press, broadcasts only news and a Client, listens to two broadcasting Ports (Trade and News) and submits orders to the Trade Server. So far I've created the basic communication functionalities like this:

39382-test.gif

When I click Listen on Trade Server, it does the following:

void start(object o)  
{  
    broadcastPoint = new IPEndPoint(IPAddress.Parse(Constants.TRADE_NET), Constants.TRADE_PORT);  
    receivePoint = new IPEndPoint(IPAddress.Parse(Constants.ORDER_IP), Constants.ORDER_PORT);  
    broadcaster = new Socket(SocketType.Dgram, ProtocolType.Udp) { EnableBroadcast = true };  
    receiver = new Socket(SocketType.Dgram, ProtocolType.Udp);  
    receiver.Bind(receivePoint);  
    receiveSource = new CancellationTokenSource();  
    Task.Run(receiveOrder, receiveSource.Token);  
    Task.Run(processOrder);  
}  

receiveOrder function just puts the buffer in a ConcurrentQueue and restarts receiving orders:

void receiveOrder()  
{  
    var buffer = new byte[Constants.ORDER_SIZE];  
    while (!receiveSource.IsCancellationRequested)  
    {  
        receiver.Receive(buffer);  
        orderQueue.Enqueue(buffer.ToArray());  
    }  
}  

right now processOrder only dequeues and broadcasts:

void processOrder()  
{  
    while (true)  
    {  
        if (orderQueue.Count > 0)  
        {  
            byte[] buffer;  
            while (!orderQueue.TryDequeue(out buffer)) { }  
            broadcaster.SendTo(buffer, broadcastPoint);  
        }  
        else Thread.Sleep(100);  
    }  
}  

BUT it actually will check for execution first and then broadcast one or more orders. Press is simple, it's initialized with:

newsPoint = new IPEndPoint(IPAddress.Parse(Constants.NEWS_NET), Constants.NEWS_PORT);  
broadcaster = new Socket(SocketType.Dgram, ProtocolType.Udp) { EnableBroadcast = true };  

and on button click it broadcasts each new and sleeps for 50ms:

void broadcast(object o)  
{  
    foreach (var @new in News)  
    {  
        var buffer = Encoding.UTF8.GetBytes(@new);  
        broadcaster.SendTo(buffer, newsPoint);  
        Thread.Sleep(50);  
    }  
    ...  
}  

Client's initialized with these:

tradePoint = new IPEndPoint(IPAddress.Any, Constants.TRADE_PORT);  
newsPoint = new IPEndPoint(IPAddress.Any, Constants.NEWS_PORT);  
orderPoint = new IPEndPoint(IPAddress.Parse(Constants.ORDER_IP), Constants.ORDER_PORT);            
tradeClient = new Socket(SocketType.Dgram, ProtocolType.Udp);  
newsClient = new Socket(SocketType.Dgram, ProtocolType.Udp);  
orderClient = new Socket(SocketType.Dgram, ProtocolType.Udp);  
tradeClient.Bind(tradePoint);  
newsClient.Bind(newsPoint);  
receiveSource = new CancellationTokenSource();  
Task.Run(receiveOrder, receiveSource.Token);  
Task.Run(receiveNews, receiveSource.Token);  
Task.Run(processOrder, receiveSource.Token);  
SubmitOrder = new Command(submitOrder, (o) => true);  

Client's receiveOrder and receiveNews is similar to receiveOrder of Trade Server:

void receiveOrder()  
{  
    var buffer = new byte[Constants.ORDER_SIZE];  
    while (!receiveSource.IsCancellationRequested)  
    {  
        tradeClient.Receive(buffer);  
        orderQueue.Enqueue(buffer.ToArray());  
    }  
}  

processOrder, right now, dequeues order from orderQueue and displays that on UI with an ObservableCollection and Client submits order in SubmitOrder function like this:

void submitOrder(object o)  
{  
    orderClient.SendTo(Encoding.UTF8.GetBytes("Order " + no++), orderPoint);  
}  

ORDER_SIZE is 88 bytes and NEWS_SIZE is 1024 bytes.

all that left is to design the UI, do some computation and have another TCP Socket on both Trade Server and Client to send/receive queued/processedOrder when it first connects. BUT before that the relevant question is should UDP be used for this type of application?

Developer technologies | Windows Presentation Foundation
0 comments No comments
{count} votes

Accepted answer
  1. Duane Arnold 3,216 Reputation points
    2020-11-12T19:22:43.093+00:00

    Myself, I wouldn't use UDP. With UDP, packets can be lost and come out of order.

    You don't see a Web based solution, which is typical client/server, using UDP they use TCP, becuase UDP is for messages and TCP is for data. Traditional client/server solutions that send data use TCP.

    If one wants reliability, then one chooses TCP.

    https://medium.com/@yoursproductly/tcp-vs-udp-38b10bb1bbf3
    https://www.vpnmentor.com/blog/tcp-vs-udp/

    1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. Emon Haque 3,176 Reputation points
    2020-11-12T18:49:59.917+00:00

    After thanking about it for a while, what I've realised is: it will lose data in Trade Server's receiveOrder function because all clients' orders will be accumulated in one internal buffer and at some point it might be exhausted if there's too many clients. Other than that, the rest is alright I think.

    Clients' receiveOrder will not lose data because server will take time, in between broadcast, to process order and by that time clients will be able to enqueue the received order and get back to hang on Receive. receiveNews, probably, will also work because of the 50ms delay in Press.

    Is there any way to increase the internal buffer size of the Trade Server?

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.