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. ATL / WTL / STL
  4. unexpected address value in WSABUF ( RESOLVED )

unexpected address value in WSABUF ( RESOLVED )

Scheduled Pinned Locked Moved ATL / WTL / STL
c++csharpvisual-studiocomtesting
13 Posts 2 Posters 24 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.
  • B Offline
    B Offline
    bkelly13
    wrote on last edited by
    #1

    Windows 7, Visual Studio 2010, C++ structure m_common_data contains:

    struct st_common_data
    {...
    LPWSABUF p_lpwsabuf_array[ TCP_SERVER_PACKET_BUFFER_SIZE ];

    where the constant has the value 16. The main app dot H contains:

    char m_send_buf_array[ TCP_SERVER_PACKET_BUFFER_SIZE ][TEST_BUFFER_SIZE];

    where TEST_BUFFER_SIZE is an arbitrary 1024 for initial testing. the main app dot CPP initializes all with this, and after some debugging variables were installed looks like this:

    void CTest_ServerDlg::Initialize_Send_Buffers()
    {
    unsigned int db1, db2a, db2b, db2c, db2d, db3, db4, db5, db6, db7;
    for( int i = 0; i < TCP_SERVER_PACKET_BUFFER_SIZE; i ++ )
    {
    for( int j = 0; j < TEST_BUFFER_SIZE; j ++ )
    {
    m_send_buf_array[ i ][ j ] = ( ( i * 5 ) + j ) % 255;
    }

        db1 = (unsigned int) &m\_send\_buf\_array\[ i \]\[0\];
        db2a = m\_send\_buf\_array\[ i \]\[0\];
        db2b = m\_send\_buf\_array\[ i \]\[1\];
        db2c = m\_send\_buf\_array\[ i \]\[2\];
        db2d = m\_send\_buf\_array\[ i \]\[3\];
        db3 = sizeof( m\_send\_buf\_array\[ i \] );
        db4 = (unsigned int) &m\_common\_data;
        db5 = (unsigned int) &( m\_common\_data.p\_lpwsabuf\_array\[ i \] );
        db6 = (unsigned int) &( m\_common\_data.p\_lpwsabuf\_array\[ i \]->buf );
    
        m\_common\_data.p\_lpwsabuf\_array\[ i \]->buf = &m\_send\_buf\_array\[ i \]\[0\];  // error
        m\_common\_data.p\_lpwsabuf\_array\[ i \]->len = sizeof( m\_send\_buf\_array\[ i \] );
    }
    

    When stopped on the first time through the i loop, i = 0. The debugger shows db1 = a valid looking address dba,b,c, and d contain: 0, 1, 2, 3, as expected db3 = 0X400, expected db4 looks like a valid address db5 = db4 + 0xF0 again expected because of items not shown. db6 shows the value 4. db6 is the value I do not comprehend. I expected a valid address here, specifically I expected the value to be 4 larger than db5 because the ->buf item of structure WSABUF is the second item in the structure. Please explain why db6 has the value 4 rather than the address of item ->buf.

    Thank you for your time If you work with telemetry, please check this bulletin board: www.irigbb.com

    L 1 Reply Last reply
    0
    • B bkelly13

      Windows 7, Visual Studio 2010, C++ structure m_common_data contains:

      struct st_common_data
      {...
      LPWSABUF p_lpwsabuf_array[ TCP_SERVER_PACKET_BUFFER_SIZE ];

      where the constant has the value 16. The main app dot H contains:

      char m_send_buf_array[ TCP_SERVER_PACKET_BUFFER_SIZE ][TEST_BUFFER_SIZE];

      where TEST_BUFFER_SIZE is an arbitrary 1024 for initial testing. the main app dot CPP initializes all with this, and after some debugging variables were installed looks like this:

      void CTest_ServerDlg::Initialize_Send_Buffers()
      {
      unsigned int db1, db2a, db2b, db2c, db2d, db3, db4, db5, db6, db7;
      for( int i = 0; i < TCP_SERVER_PACKET_BUFFER_SIZE; i ++ )
      {
      for( int j = 0; j < TEST_BUFFER_SIZE; j ++ )
      {
      m_send_buf_array[ i ][ j ] = ( ( i * 5 ) + j ) % 255;
      }

          db1 = (unsigned int) &m\_send\_buf\_array\[ i \]\[0\];
          db2a = m\_send\_buf\_array\[ i \]\[0\];
          db2b = m\_send\_buf\_array\[ i \]\[1\];
          db2c = m\_send\_buf\_array\[ i \]\[2\];
          db2d = m\_send\_buf\_array\[ i \]\[3\];
          db3 = sizeof( m\_send\_buf\_array\[ i \] );
          db4 = (unsigned int) &m\_common\_data;
          db5 = (unsigned int) &( m\_common\_data.p\_lpwsabuf\_array\[ i \] );
          db6 = (unsigned int) &( m\_common\_data.p\_lpwsabuf\_array\[ i \]->buf );
      
          m\_common\_data.p\_lpwsabuf\_array\[ i \]->buf = &m\_send\_buf\_array\[ i \]\[0\];  // error
          m\_common\_data.p\_lpwsabuf\_array\[ i \]->len = sizeof( m\_send\_buf\_array\[ i \] );
      }
      

      When stopped on the first time through the i loop, i = 0. The debugger shows db1 = a valid looking address dba,b,c, and d contain: 0, 1, 2, 3, as expected db3 = 0X400, expected db4 looks like a valid address db5 = db4 + 0xF0 again expected because of items not shown. db6 shows the value 4. db6 is the value I do not comprehend. I expected a valid address here, specifically I expected the value to be 4 larger than db5 because the ->buf item of structure WSABUF is the second item in the structure. Please explain why db6 has the value 4 rather than the address of item ->buf.

      Thank you for your time If you work with telemetry, please check this bulletin board: www.irigbb.com

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #2

      Your declaration

      LPWSABUF p_lpwsabuf_array[ TCP_SERVER_PACKET_BUFFER_SIZE ];

      says that p_lpwsabuf_array is an array of LPWSABUF items, that is pointers to WSABUF structures. Are you sure that this is what youe meant, rather than an array of actual structures?

      B 2 Replies Last reply
      0
      • L Lost User

        Your declaration

        LPWSABUF p_lpwsabuf_array[ TCP_SERVER_PACKET_BUFFER_SIZE ];

        says that p_lpwsabuf_array is an array of LPWSABUF items, that is pointers to WSABUF structures. Are you sure that this is what youe meant, rather than an array of actual structures?

        B Offline
        B Offline
        bkelly13
        wrote on last edited by
        #3

        The Microsoft web pages here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms741542(v=vs.85).aspx[^] has:

        typedef struct __WSABUF {
        u_long len;
        char FAR *buf;
        } WSABUF

        Edit this line:

        m_common_data.p_lpwsabuf_array[ i ]->buf ( <- delete ">buf" and retype the > ) = &m_send_buf_array[ i ][0];

        If is delete the end of the assignment and retype in the ->, intellisense says the options are len and buf. Going on that I think the declaration and statement are correct. Are they incorrect?

        Thank you for your time If you work with telemetry, please check this bulletin board: www.irigbb.com

        L 2 Replies Last reply
        0
        • B bkelly13

          The Microsoft web pages here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms741542(v=vs.85).aspx[^] has:

          typedef struct __WSABUF {
          u_long len;
          char FAR *buf;
          } WSABUF

          Edit this line:

          m_common_data.p_lpwsabuf_array[ i ]->buf ( <- delete ">buf" and retype the > ) = &m_send_buf_array[ i ][0];

          If is delete the end of the assignment and retype in the ->, intellisense says the options are len and buf. Going on that I think the declaration and statement are correct. Are they incorrect?

          Thank you for your time If you work with telemetry, please check this bulletin board: www.irigbb.com

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #4

          I'm not sure what you are saying here, but my previous question still stands. Is p_lpwsabuf_array supposed to be an array of WSABUF structures, or an array of pointers? There is a big difference.

          B 1 Reply Last reply
          0
          • B bkelly13

            The Microsoft web pages here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms741542(v=vs.85).aspx[^] has:

            typedef struct __WSABUF {
            u_long len;
            char FAR *buf;
            } WSABUF

            Edit this line:

            m_common_data.p_lpwsabuf_array[ i ]->buf ( <- delete ">buf" and retype the > ) = &m_send_buf_array[ i ][0];

            If is delete the end of the assignment and retype in the ->, intellisense says the options are len and buf. Going on that I think the declaration and statement are correct. Are they incorrect?

            Thank you for your time If you work with telemetry, please check this bulletin board: www.irigbb.com

            L Offline
            L Offline
            Lost User
            wrote on last edited by
            #5

            Supplementary point. Since p_lpwsabuf_array is declared as an array of pointers, each element needs to be initialised with the address of a real WSABUF.

            1 Reply Last reply
            0
            • L Lost User

              I'm not sure what you are saying here, but my previous question still stands. Is p_lpwsabuf_array supposed to be an array of WSABUF structures, or an array of pointers? There is a big difference.

              B Offline
              B Offline
              bkelly13
              wrote on last edited by
              #6

              I am expecting an array of structures. The MS page shows this:

              typedef struct __WSABUF { u_long len; char FAR *buf; } WSABUF, *LPWSABUF;

              I am uncertain as to how the phrase ..;., *LPWSABUF; is read. The line of code in question is an assignment to:

              m_common_data.p_lpwsabuf_array[ i ]->buf

              When I get here:

              m_common_data.p_lpwsabuf_array[ i ]

              and type in the two characters -> Intellisense prompts me for the fields len and buf. I interpert that as saying Intellisens interperts the declaration as an array of structure, each of which has a pointer to the data to be sent. But when I try to show the address of the buf pointer, (not the value of the pointer, but the address of where the pointer is held in the structure), the debugger provides an address of 4. Since that is a contradition, there is something I am misinterperting. Edit: I should change the name from p_lpwsabuf_array to lpwsabuf_array as the intent is an array of structure. The p_ prefix is misleading. EDIT: She key here seems to be that I don't know how to read the declaration of WSABUF, *LPWSABUF. I tried using an array of WSABUF but WSASend demands LPWSABUF. When I use that in the declaration I am unable to assign an address to the ->buf pointer. If the original declaration is WSABUF, how is that cast to LPWSABUF so WSASend will accept it? If the other way around, how is the code to be changed to assign an address to ->buf in the code I posted?

              Thank you for your time If you work with telemetry, please check this bulletin board: www.irigbb.com

              L 1 Reply Last reply
              0
              • B bkelly13

                I am expecting an array of structures. The MS page shows this:

                typedef struct __WSABUF { u_long len; char FAR *buf; } WSABUF, *LPWSABUF;

                I am uncertain as to how the phrase ..;., *LPWSABUF; is read. The line of code in question is an assignment to:

                m_common_data.p_lpwsabuf_array[ i ]->buf

                When I get here:

                m_common_data.p_lpwsabuf_array[ i ]

                and type in the two characters -> Intellisense prompts me for the fields len and buf. I interpert that as saying Intellisens interperts the declaration as an array of structure, each of which has a pointer to the data to be sent. But when I try to show the address of the buf pointer, (not the value of the pointer, but the address of where the pointer is held in the structure), the debugger provides an address of 4. Since that is a contradition, there is something I am misinterperting. Edit: I should change the name from p_lpwsabuf_array to lpwsabuf_array as the intent is an array of structure. The p_ prefix is misleading. EDIT: She key here seems to be that I don't know how to read the declaration of WSABUF, *LPWSABUF. I tried using an array of WSABUF but WSASend demands LPWSABUF. When I use that in the declaration I am unable to assign an address to the ->buf pointer. If the original declaration is WSABUF, how is that cast to LPWSABUF so WSASend will accept it? If the other way around, how is the code to be changed to assign an address to ->buf in the code I posted?

                Thank you for your time If you work with telemetry, please check this bulletin board: www.irigbb.com

                L Offline
                L Offline
                Lost User
                wrote on last edited by
                #7

                typedef struct __WSABUF { u_long len; char FAR *buf; } WSABUF, *LPWSABUF;

                You read the above as struct __WSABUF declares a structure whose contents are declared within the braces following. The typedef specifier creates synonyms for the following declaration, which in their turn can be modified types. In this case WSABUF is a synonym for the preceding structure declaration. *LPWSABUF is a synonym for a pointer to the structure: the preceding asterisk tells us that it is a pointer. So the declaration

                LPWSABUF p_lpwsabuf_array[ TCP_SERVER_PACKET_BUFFER_SIZE ];

                declares an array of pointers. However according to the documentation for WSASend[^], the second parameter is a pointer to an array of WSABUF structures, not pointers, so it should be declared, and initialised something like:

                WSABUF wsabuf_array[ TCP_SERVER_PACKET_BUFFER_SIZE ];

                // ...

                for (int i = 0; i < TCP_SERVER_PACKET_BUFFER_SIZE; ++i)
                {
                wsabuf_array[i].len = 16; // set the length of the buffer in this structure element
                wsabuf_array[i].buf = new char[16]; // allocate a character array and save its address in the structure
                }

                Then when you need to use a pointer to the array on a call to WSASEND you just use the array name, which the compiler converts to a pointer to the first element thus:

                int result = WSASend(socket, wsabuf_array, count, ... etc)

                Does that make sense?

                B 1 Reply Last reply
                0
                • L Lost User

                  typedef struct __WSABUF { u_long len; char FAR *buf; } WSABUF, *LPWSABUF;

                  You read the above as struct __WSABUF declares a structure whose contents are declared within the braces following. The typedef specifier creates synonyms for the following declaration, which in their turn can be modified types. In this case WSABUF is a synonym for the preceding structure declaration. *LPWSABUF is a synonym for a pointer to the structure: the preceding asterisk tells us that it is a pointer. So the declaration

                  LPWSABUF p_lpwsabuf_array[ TCP_SERVER_PACKET_BUFFER_SIZE ];

                  declares an array of pointers. However according to the documentation for WSASend[^], the second parameter is a pointer to an array of WSABUF structures, not pointers, so it should be declared, and initialised something like:

                  WSABUF wsabuf_array[ TCP_SERVER_PACKET_BUFFER_SIZE ];

                  // ...

                  for (int i = 0; i < TCP_SERVER_PACKET_BUFFER_SIZE; ++i)
                  {
                  wsabuf_array[i].len = 16; // set the length of the buffer in this structure element
                  wsabuf_array[i].buf = new char[16]; // allocate a character array and save its address in the structure
                  }

                  Then when you need to use a pointer to the array on a call to WSASEND you just use the array name, which the compiler converts to a pointer to the first element thus:

                  int result = WSASend(socket, wsabuf_array, count, ... etc)

                  Does that make sense?

                  B Offline
                  B Offline
                  bkelly13
                  wrote on last edited by
                  #8

                  Good Morning To You, It is 5:50 AM here and I wanted to check for replies but am not yet awake enough to write code. It sort of makes sense. It makes enough sense for me to create a new solution and try some examples with your comments to see how they work out. I'll do that before getting back to my main project. I really appreciate you taking the time to explain this.

                  Thank you for your time If you work with telemetry, please check this bulletin board: www.irigbb.com

                  1 Reply Last reply
                  0
                  • L Lost User

                    Your declaration

                    LPWSABUF p_lpwsabuf_array[ TCP_SERVER_PACKET_BUFFER_SIZE ];

                    says that p_lpwsabuf_array is an array of LPWSABUF items, that is pointers to WSABUF structures. Are you sure that this is what youe meant, rather than an array of actual structures?

                    B Offline
                    B Offline
                    bkelly13
                    wrote on last edited by
                    #9

                    Hello Richard, Your last post is proving very helpful. I have made many steps forward. Now I arrive near the final stage of getting my syntax correct. Class C_TCP_API_Server handles all the details of sending data to a client. The data originates with these two declarations:

                    WSABUF wsabuf_array[ TCP_SERVER_PACKET_BUFFER_SIZE ];
                    LPWSABUF p_lpwsabuf;

                    There will be 16 buffers and p_lpwsabuf is initialized with:

                    m_common_data.p_lpwsabuf = m_common_data.wsabuf_array

                    Deep down in the send class is:

                    m_send_status = WSASend(
                    m_client_socket,
                    mp_lpwsabuf[ *mp_send_array_index ],
                    1, // one buffer for now
                    NULL, // I will add this later
                    NULL, // no flags
                    m_overlapped[ *mp_send_array_index ],
                    NULL ); // no completion routine

                    where mp_lpwsabuff is declared as

                    LPWSABUF mp_lpwsabuf;

                    And its value is traced back to the first declaration shown above. The problem is this compiler error:

                    Quote:

                    1>d:\bryan\common_code\c_tcp_api_server.cpp(1124): error C2664: 'WSASend' : cannot convert parameter 2 from '_WSABUF' to 'LPWSABUF' 1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

                    Parameter two is declared as LPWSABUF. WSASend has LPWSABUF as its second argument. I do not understand why the compiler wants to convert from _WSABUF to LPWSABUF.

                    Thank you for your time If you work with telemetry, please check this bulletin board: www.irigbb.com

                    L 1 Reply Last reply
                    0
                    • B bkelly13

                      Hello Richard, Your last post is proving very helpful. I have made many steps forward. Now I arrive near the final stage of getting my syntax correct. Class C_TCP_API_Server handles all the details of sending data to a client. The data originates with these two declarations:

                      WSABUF wsabuf_array[ TCP_SERVER_PACKET_BUFFER_SIZE ];
                      LPWSABUF p_lpwsabuf;

                      There will be 16 buffers and p_lpwsabuf is initialized with:

                      m_common_data.p_lpwsabuf = m_common_data.wsabuf_array

                      Deep down in the send class is:

                      m_send_status = WSASend(
                      m_client_socket,
                      mp_lpwsabuf[ *mp_send_array_index ],
                      1, // one buffer for now
                      NULL, // I will add this later
                      NULL, // no flags
                      m_overlapped[ *mp_send_array_index ],
                      NULL ); // no completion routine

                      where mp_lpwsabuff is declared as

                      LPWSABUF mp_lpwsabuf;

                      And its value is traced back to the first declaration shown above. The problem is this compiler error:

                      Quote:

                      1>d:\bryan\common_code\c_tcp_api_server.cpp(1124): error C2664: 'WSASend' : cannot convert parameter 2 from '_WSABUF' to 'LPWSABUF' 1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

                      Parameter two is declared as LPWSABUF. WSASend has LPWSABUF as its second argument. I do not understand why the compiler wants to convert from _WSABUF to LPWSABUF.

                      Thank you for your time If you work with telemetry, please check this bulletin board: www.irigbb.com

                      L Offline
                      L Offline
                      Lost User
                      wrote on last edited by
                      #10

                      The pointer mp_lpwsabuf points to an array of buffers ([ 0 .. N ]). However, the expression mp_lpwsabuf[N] is a reference to the Nth element in the array, it is no longer a pointer (yes, I know it sounds weird). To get a pointer to the Nth element of the array you need to get the address of (or addressof) the Nth element. You can do that with the addressof operator (&) or by adding the index value to the pointer thus:

                      // Option 1
                      m_send_status = WSASend(
                      m_client_socket,
                      &mp_lpwsabuf[ *mp_send_array_index ], // use addressof operator
                      1, // one buffer for now
                      NULL, // I will add this later
                      NULL, // no flags
                      m_overlapped[ *mp_send_array_index ],
                      NULL ); // no completion routine

                      // Option 2
                      m_send_status = WSASend(
                      m_client_socket,
                      mp_lpwsabuf + *mp_send_array_index, // add offset to pointer
                      1, // one buffer for now
                      NULL, // I will add this later
                      NULL, // no flags
                      m_overlapped[ *mp_send_array_index ],
                      NULL ); // no completion routine

                      Remembering that adding N to a pointer to an array of structures will actually add (N times the size in bytes of the structure). I'm interested to know why you need the indirection operator on the mp_send_array_index variable.

                      B 1 Reply Last reply
                      0
                      • L Lost User

                        The pointer mp_lpwsabuf points to an array of buffers ([ 0 .. N ]). However, the expression mp_lpwsabuf[N] is a reference to the Nth element in the array, it is no longer a pointer (yes, I know it sounds weird). To get a pointer to the Nth element of the array you need to get the address of (or addressof) the Nth element. You can do that with the addressof operator (&) or by adding the index value to the pointer thus:

                        // Option 1
                        m_send_status = WSASend(
                        m_client_socket,
                        &mp_lpwsabuf[ *mp_send_array_index ], // use addressof operator
                        1, // one buffer for now
                        NULL, // I will add this later
                        NULL, // no flags
                        m_overlapped[ *mp_send_array_index ],
                        NULL ); // no completion routine

                        // Option 2
                        m_send_status = WSASend(
                        m_client_socket,
                        mp_lpwsabuf + *mp_send_array_index, // add offset to pointer
                        1, // one buffer for now
                        NULL, // I will add this later
                        NULL, // no flags
                        m_overlapped[ *mp_send_array_index ],
                        NULL ); // no completion routine

                        Remembering that adding N to a pointer to an array of structures will actually add (N times the size in bytes of the structure). I'm interested to know why you need the indirection operator on the mp_send_array_index variable.

                        B Offline
                        B Offline
                        bkelly13
                        wrote on last edited by
                        #11

                        Good Morning, At least for me. That makes sense after thinking a bit. Lets see if I got that right: WSASend needs to have direct access to the LPWSABUF pointer so it can increment the pointer through the multiple WSABUFs and send several buffers on a single call. Hence, give it the address of that guy. Regarding the strange line: m_overlapped[ *mp_send_array_index ], The main app creates and owns the buffers to output to a client via TCP/IP. It creates a structure to hold the pointers to the buffers. The pointer to the buffers are in an array of WSABUF and there are two integers, load_array_index and send_array_index. Main app uses the load_index to keep track of which WSABUF item to use next and C_TCP_API_Server (presented momentarily) uses send_index to keep track of which one to send next. The class to manage the TCP/IP operations is C_Server_Thread and is started as a thread from main_app and the structure is passed via the one pointer. That C_Server_Thread has events to trigger/control it and other performance monitoring variables. It creates class C_TCP_API_Server to manage the details of the TCP/IP. That class needs only a subset of the structure passed. So C_Server_Thread hands off a pointer to the index values. Hence, the pointer to the index and the * dereference character. Elsewhere: C_TCP_API_Server created its own thread, a completion thread. It collects the events from the I/O completion, a unique event assigned to each item in the array of buffers. It gets the event and simply NULLs the address and zeroes the length value in the WSABUF, and everyone knows that buffer is ready to be used again. It is a bit complicated but the end application will handle a stream of 12 megabits/second and must extract parameters real time and pass them on. Some of those parameters are bit wise meaning a 16 bit word will have 16 parameters, each of which must be separated and given its own name. (Actually a tag number, which is a direct reference to the name.) Then the parameters are passed on to a display system. There will be up to four copies of this app running at one time because as many as four of these telemetry transmitters may be active at one time. It must be fast and efficient to display the data in real time. (Ok, to be very technical, very near real time) Safety must be able to see many of these parameters and have the ability to destroy it if things go badly. I have an early version of the app running but it uses blocking TCP which is can be a real pain. This ap

                        L 1 Reply Last reply
                        0
                        • B bkelly13

                          Good Morning, At least for me. That makes sense after thinking a bit. Lets see if I got that right: WSASend needs to have direct access to the LPWSABUF pointer so it can increment the pointer through the multiple WSABUFs and send several buffers on a single call. Hence, give it the address of that guy. Regarding the strange line: m_overlapped[ *mp_send_array_index ], The main app creates and owns the buffers to output to a client via TCP/IP. It creates a structure to hold the pointers to the buffers. The pointer to the buffers are in an array of WSABUF and there are two integers, load_array_index and send_array_index. Main app uses the load_index to keep track of which WSABUF item to use next and C_TCP_API_Server (presented momentarily) uses send_index to keep track of which one to send next. The class to manage the TCP/IP operations is C_Server_Thread and is started as a thread from main_app and the structure is passed via the one pointer. That C_Server_Thread has events to trigger/control it and other performance monitoring variables. It creates class C_TCP_API_Server to manage the details of the TCP/IP. That class needs only a subset of the structure passed. So C_Server_Thread hands off a pointer to the index values. Hence, the pointer to the index and the * dereference character. Elsewhere: C_TCP_API_Server created its own thread, a completion thread. It collects the events from the I/O completion, a unique event assigned to each item in the array of buffers. It gets the event and simply NULLs the address and zeroes the length value in the WSABUF, and everyone knows that buffer is ready to be used again. It is a bit complicated but the end application will handle a stream of 12 megabits/second and must extract parameters real time and pass them on. Some of those parameters are bit wise meaning a 16 bit word will have 16 parameters, each of which must be separated and given its own name. (Actually a tag number, which is a direct reference to the name.) Then the parameters are passed on to a display system. There will be up to four copies of this app running at one time because as many as four of these telemetry transmitters may be active at one time. It must be fast and efficient to display the data in real time. (Ok, to be very technical, very near real time) Safety must be able to see many of these parameters and have the ability to destroy it if things go badly. I have an early version of the app running but it uses blocking TCP which is can be a real pain. This ap

                          L Offline
                          L Offline
                          Lost User
                          wrote on last edited by
                          #12

                          bkelly13 wrote:

                          It is a bit complicated but the end application will handle a stream of 12 megabits/second and must extract parameters real time and pass them on.

                          Yes, I think I recall you explaining that in an earlier thread.

                          bkelly13 wrote:

                          Thank for so much for your time and mostly for your patience.

                          You are welcome. It's easy to be patient with people who so obviously try so hard to do their own work, and just need a little assistance from time to time. And to be honest, I still struggle with a number of C++ and Windows concepts.

                          B 1 Reply Last reply
                          0
                          • L Lost User

                            bkelly13 wrote:

                            It is a bit complicated but the end application will handle a stream of 12 megabits/second and must extract parameters real time and pass them on.

                            Yes, I think I recall you explaining that in an earlier thread.

                            bkelly13 wrote:

                            Thank for so much for your time and mostly for your patience.

                            You are welcome. It's easy to be patient with people who so obviously try so hard to do their own work, and just need a little assistance from time to time. And to be honest, I still struggle with a number of C++ and Windows concepts.

                            B Offline
                            B Offline
                            bkelly13
                            wrote on last edited by
                            #13

                            What makes this double, or triply difficult is that I am the only one in our detachment writing C/C++ code, the only one that uses Visual Studio, and the only one doing this level of work. You, and I, can imagine how much better my code would be if I had someone to present it to and review. I try to make up for that deficiency as best I can, but there will never be a substitute for another person's perspective. So your help is even more appreciated than is immediately apparent. Edit: And I am a bit proud of my thinking that led to creating a second thread to handle the completion events. That really simplified the class C_TCP_API_Server by removing all that stuff from the sending code and the code that manages the connection. I am sure its been done many times before, but this has been a pretty cool learning experience. PLUS, my managers do understand the complexity and I have the luxury of time.

                            Thank you for your time If you work with telemetry, please check this bulletin board: www.irigbb.com

                            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