Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Overlapped IO sockets sending and receiving at the same time

Overlapped IO sockets sending and receiving at the same time

Scheduled Pinned Locked Moved C / C++ / MFC
question
5 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    jtlancer
    wrote on last edited by
    #1

    I'm writing some port forwarding code and don't have control over the size of the data being sent/received. So I need to always have a recv queued even though I may possible be in the middle of a write (since my overlapped sockets are reading and writing to and from each other whenever recv gets new data on either side). How do I allow for the possibility that an unblocked worker thread could be processing a read or a write? IOW how do I know if GetQueuedCompletionStatus was unblocked for a pending WSARecv or WSASend? thanks. ---jt

    Richard Andrew x64R 1 Reply Last reply
    0
    • J jtlancer

      I'm writing some port forwarding code and don't have control over the size of the data being sent/received. So I need to always have a recv queued even though I may possible be in the middle of a write (since my overlapped sockets are reading and writing to and from each other whenever recv gets new data on either side). How do I allow for the possibility that an unblocked worker thread could be processing a read or a write? IOW how do I know if GetQueuedCompletionStatus was unblocked for a pending WSARecv or WSASend? thanks. ---jt

      Richard Andrew x64R Offline
      Richard Andrew x64R Offline
      Richard Andrew x64
      wrote on last edited by
      #2

      I would do it by using separate event handles for the read and the write, and then inspecting the return value from your wait function to see which event handle was signaled. EDIT ========== OK, I see what you're doing. You're polling GetQueuedCompletionStatus, right? Well that's not the optimum model to use with completion ports, as you see. You're much better off using the OVERLAPPED structure when you call WSARecv and WSASend, and then seeing which event handle is signaled. Here's the pseudo code:

      ORecv = new OVERLAPPED struct;
      Set ORecv's event handle to your Recv event;
      call WSARecv with ORecv;

      OSend = new OVERLAPPED struct;
      Set OSend's event handle to your Send event;
      call WSASend with OSend;

      Wait on the two handles;

      See which handle was signalled,
      and then call GetQueuedCompletionStatus;

      The difficult we do right away... ...the impossible takes slightly longer.

      J 1 Reply Last reply
      0
      • Richard Andrew x64R Richard Andrew x64

        I would do it by using separate event handles for the read and the write, and then inspecting the return value from your wait function to see which event handle was signaled. EDIT ========== OK, I see what you're doing. You're polling GetQueuedCompletionStatus, right? Well that's not the optimum model to use with completion ports, as you see. You're much better off using the OVERLAPPED structure when you call WSARecv and WSASend, and then seeing which event handle is signaled. Here's the pseudo code:

        ORecv = new OVERLAPPED struct;
        Set ORecv's event handle to your Recv event;
        call WSARecv with ORecv;

        OSend = new OVERLAPPED struct;
        Set OSend's event handle to your Send event;
        call WSASend with OSend;

        Wait on the two handles;

        See which handle was signalled,
        and then call GetQueuedCompletionStatus;

        The difficult we do right away... ...the impossible takes slightly longer.

        J Offline
        J Offline
        jtlancer
        wrote on last edited by
        #3

        Thanks. I'm not polling, I am using the overlapped structure in send and recv but hadn't thought to use separate structures for send versus recv. That should work...thanks.

        M 1 Reply Last reply
        0
        • J jtlancer

          Thanks. I'm not polling, I am using the overlapped structure in send and recv but hadn't thought to use separate structures for send versus recv. That should work...thanks.

          M Offline
          M Offline
          Mark Salsbery
          wrote on last edited by
          #4

          I personally don't like the idea of waiting on OVERLAPPED handles. I'd much rather not introduce more (or any) synchronization objects to the IOCP handler threads but instead let the IOCP do its magic with all threads waiting on GetQueuedCompletionStatus. I take advantage of the fact that the same overlapped structure pointer you pass to an overlapped function will be returned to you so I use extended OVERLAPPED structures like the one in this article[^]

          typedef struct _OVERLAPPEDPLUS {
          OVERLAPPED ol;
          SOCKET s, sclient;
          int OpCode;
          WSABUF wbuf;
          DWORD dwBytes, dwFlags;
          // other useful information
          } OVERLAPPEDPLUS;

          The opcode can be used to indicate read or write (and many other things including non-I/O tasks you want to queue on the IOCP). Also gives you a handy place to keep buffers associated with the operation.

          Mark Salsbery :java:

          Richard Andrew x64R 1 Reply Last reply
          0
          • M Mark Salsbery

            I personally don't like the idea of waiting on OVERLAPPED handles. I'd much rather not introduce more (or any) synchronization objects to the IOCP handler threads but instead let the IOCP do its magic with all threads waiting on GetQueuedCompletionStatus. I take advantage of the fact that the same overlapped structure pointer you pass to an overlapped function will be returned to you so I use extended OVERLAPPED structures like the one in this article[^]

            typedef struct _OVERLAPPEDPLUS {
            OVERLAPPED ol;
            SOCKET s, sclient;
            int OpCode;
            WSABUF wbuf;
            DWORD dwBytes, dwFlags;
            // other useful information
            } OVERLAPPEDPLUS;

            The opcode can be used to indicate read or write (and many other things including non-I/O tasks you want to queue on the IOCP). Also gives you a handy place to keep buffers associated with the operation.

            Mark Salsbery :java:

            Richard Andrew x64R Offline
            Richard Andrew x64R Offline
            Richard Andrew x64
            wrote on last edited by
            #5

            Wow. That's a great tip. Thanks for sharing!

            The difficult we do right away... ...the impossible takes slightly longer.

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups