Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6868279
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 27, 20262026-05-27T03:24:52+00:00 2026-05-27T03:24:52+00:00

I have a UDP server that reflects every ping message it receives (this works

  • 0

I have a UDP server that reflects every ping message it receives (this works well I think). I the client side I would then like to do two things:

  1. make sure that I fired off N (e.g. 10000) messages, and
  2. count the number of correctly received responses.

It seems that either because of the nature of UDP or because of the forkIO thing, my client code below ends prematurely/does not do any counting at all.

Also I am very surprised to see that the function tryOnePing returns 250 times the Int 4. Why could this be?

main = withSocketsDo $ do
        s <- socket AF_INET Datagram defaultProtocol
        hostAddr <- inet_addr host
        thread <- forkIO $ receiveMessages s
        -- is there any better way to eg to run that in parallel and make sure
        -- that sending/receiving are asynchronous? 


        -- forM_ [0 .. 10000] $ \i -> do
              -- sendTo s "ping" (SockAddrInet port hostAddr)
        -- actually this would be preferred since I can discard the Int 4 that
        -- it returns but forM or forM_ are out of scope here?

        let tryOnePing i = sendTo s "ping" (SockAddrInet port hostAddr)
        pings <- mapM tryOnePing [0 .. 1000]
        let c = length $ filter (\x -> x==4) pings

        -- killThread thread
        -- took that out to make sure the function receiveMessages does not
        -- end prematurely. still seems that it does

        sClose s
        print c
        -- return()

receiveMessages :: Socket -> IO ()
receiveMessages socket = forever $ do
        -- also tried here forM etc. instead of forever but no joy
        let recOnePing i = recv socket 1024
        msg <- mapM recOnePing [0 .. 1000]
        let r = length $ filter (\x -> x=="PING") msg
        print r
        print "END"
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-27T03:24:53+00:00Added an answer on May 27, 2026 at 3:24 am

    The main problem here is that when your main thread finishes, all other threads gets killed automatically. You have to get the main thread to wait for the receiveMessages thread, or it will in all likelyhood simply finish before any responses have been received. One simple way of doing this is to use an MVar.

    An MVar is a synchronized cell that can either be empty or hold exactly one value. The current thread will block if it tries to take from an empty MVar or insert into a full one.
    In this case, we don’t care about the value itself, so we’ll just store a () in it.

    We’ll start with the MVar empty. Then the main thread will fork off the receiver thread, send all the packets, and try to take the value from the MVar.

    import Control.Concurrent.MVar
    
    main = withSocketsDo $ do
        -- prepare socket, same as before
    
        done <- newEmptyMVar
    
        -- we need to pass the MVar to the receiver thread so that
        -- it can use it to signal us when it's done
        forkIO $ receiveMessages sock done
    
        -- send pings, same as before
    
        takeMVar done    -- blocks until receiver thread is done
    

    In the receiver thread, we will receive all the messages and then put a () in the MVar to signal that we’re done receiving.

    receiveMessages socket done = do
        -- receive messages, same as before
    
        putMVar done ()  -- allows the main thread to be unblocked
    

    This solves the main issue, and the program runs fine on my Ubuntu laptop, but there are a couple more things you want to take care of.

    • sendTo does not guarantee that the whole string will be sent. You’ll have to check the return value to see how much was sent, and retry if not all of it was sent. This can happen even for a short message like "ping" if the send buffer is full.

    • recv requires a connected socket. You’ll want to use recvFrom instead. (Although it still works on my PC for some unknown reason).

    • Printing to standard output is not synchronized, so you might want to alter this so that the MVar will be used to communicate the number of received packets instead of just (). That way, you can do all the output from the main thread. Alternatively, use another MVar as a mutex to control access to standard output.

    Finally, I recommend reading the documentation of Network.Socket, Control.Concurrent and Control.Concurrent.MVar carefully. Most of my answer is stitched together from information found there.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a server that waits for incoming client messages and uses UDP. When
I have a C application that sends data to a UDP server every few
I have set up a UDP client/server model that can send string messages to
I have a simple UDP client server written in C++ on Ubuntu 9.10 where
I have a client and a server communicating with datagrams (UDP) in C. The
I have a udp client that is listening for multicast messages. When it gets
I have a simple UDP server that creates a new thread for processing incoming
After many hours, I have discovered that the given udp server needs the following
I have a server and client setup to use UDP communication. For now, I
I have a UDP server that I have being trying to send structures using

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.