Results 1 to 9 of 9

Thread: Send winsock messages issue

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Apr 2006
    Posts
    25

    Send winsock messages issue

    I am trying to send commands across an TCP/IP connection. I am more or less doing this:

    VB Code:
    1. '(client is a Winsock in a form)
    2. client.SendData ("#MOVE")
    3. client.SendData ("#AED")
    4. client.SendData ("#ENDMOVE")

    I want the server to respond everytime after receiving a message with "#SENDNEXT" so I know the message went through. Problem is that the messages go through at the end of the subroutine, not after each call. So, for example, after the sub, it finally sends: "#MOVE#AED#ENDMOVE#" and THEN the server sends the #SENDNEXT.

    I have this in the server:
    VB Code:
    1. Private Sub tcpserver_dataArrival(ByVal bytestotal As Long)
    2.     Dim Message As String
    3.     Call tcpserver.GetData(Message)
    4.     txttwo.Text = txttwo.Text & Message & vbCrLf & vbCrLf
    5.     txttwo.SelStart = Len(txttwo.Text)
    6.     Text1.Text = Message
    7.     Call tcpserver.SendData("#SENDNEXT")
    8. End Sub

    How can I get the server to respond after every cmd, not at the very end?

  2. #2
    Lively Member dastudios's Avatar
    Join Date
    Feb 2006
    Posts
    72

    Re: Send winsock messages issue

    The end of all messages should end with "\r\n" (vbcrlf)

    So you should be sending messages like this:
    VB Code:
    1. client.SendData ("#MOVE" & vbCrLf)
    2. client.SendData ("#AED" & vbCrLf)
    3. client.SendData ("#ENDMOVE" & vbCrLf)

    please tell me if it works

  3. #3
    Lively Member dastudios's Avatar
    Join Date
    Feb 2006
    Posts
    72

    Re: Send winsock messages issue

    ah! one thing i forgot:

    VB Code:
    1. client.SendData ("#MOVE")
    2. client.SendData ("#AED")
    3. client.SendData ("#ENDMOVE")

    if that is all in one subroutine, you wont recieve the replies from the server until the end of the sub... i would suggest doing it like this:

    VB Code:
    1. Dim MsgsToSend(2) As String
    2. Dim curMsgNum As Integer
    3.  
    4. Private Sub Form_Load()
    5.   MsgsToSend(0) = "#MOVE" & vbCrLf
    6.   MsgsToSend(1) = "#AED" & vbCrLf
    7.   MsgsToSend(2) = "#ENDMOVE" & vbCrLf
    8.   curMsgNum = 0
    9.   Client.Connect
    10. End Sub
    11.  
    12. Private Sub Client_Connect()
    13.   SendData
    14. End Sub
    15.  
    16. Private Sub Client_DataArrival(ByVal bytesTotal As Long)
    17.   Dim tmpInput As String
    18.   Client.GetData tmpInput, vbString
    19.   If tmpInput = "#SENDNEXT" & vbCrLf Then SendData
    20. End Sub
    21.  
    22. Sub SendData()
    23.   Client.SendData MsgsToSend(curMsgNum)
    24.   curMsgNum = curMsgNum + 1
    25. End Sub

    Not really that well structured, you're probably better off using a resource file or database for storing the functions but this is just to exemplify.

    Hope this helps

  4. #4
    PowerPoster
    Join Date
    Feb 2002
    Location
    Canada, Toronto
    Posts
    5,794

    Re: Send winsock messages issue

    Quote Originally Posted by McManCSU
    How can I get the server to respond after every cmd, not at the very end?
    That's because you are not waiting for the command to complectly send and you are sending another command, and of course, since Winsock is sending data by Streamming, all data is appended.
    It's as if you are sending one big string.

    Take this example:
    You send the following data
    client.SendData ("#MOVE")
    client.SendData ("#AED")
    client.SendData ("#ENDMOVE")

    Remember that it takes time for the data to send.
    There is no waiting in between each SendData, so this is what hapens:

    First this executes (this is an example, an assumption on how it works):
    client.SendData ("#MOVE")
    winsock starts sending data
    It sends "#", buffer is "MOVE"
    it sends "M", buffer is "OVE"
    it sends "O", buffer is "VE"
    Since there is no wait, it executes the next line
    client.SendData ("#AED")
    buffer is now "VE#AED"
    it sends "V", buffer is "E#AED"
    it sends "E", buffer is "E#AED"
    it sends "#", buffer is "AED"
    Since there is no wait, it executes next line
    client.SendData ("#ENDMOVE")
    buffer is now "AED#ENDMOVE"
    it sends "A"
    it sends "E"
    and so on until buffer is empty

    What happends on the client side in the mean time ?
    It received data, one byte at the time, and bufferes it.
    The winsock will raise the event when 2 things happen:

    1) Buffer reaches it's max, about ~4000 bytes
    OR
    2) It's time-out is reached ~ 100 ms (lets say, I don't know the actual time-out)

    So... now you can see why you receive the data all concatenated...

    Since your message is short, you won't reach 4000 bytes to triger the DataArrival event, and also, since the data is short, it will send pretty fast, and it's shorter than the time-out

    Therefore, you get the whole thing as one "#MOVE#AED#ENDMOVE"

    How to fix it ?

    When you send data, you have to wait for the SendComplete event, and then issue the next "SendData".

    But of course since your program has to wait for the SendComplete event, the actual sending of the data is slower.
    The SendComplete event gets trigered when the send buffer is empty.

    What can you do ?

    1) Don't use TCP/IP protocol, use the UDP protocol, it will send the data right away, regardless of how much data (as long as it's less than max buffer ~ 4000 bytes).

    2) Live with it, expect the data to arrive concatenated.
    Since data is concatenated, encapsulate the data in headers, it will still be concatenated, but at least you will know when one packet ends, and the other starts.
    In this particular case, you can search for the "#" character.
    Last edited by CVMichael; Apr 30th, 2006 at 10:56 AM.

  5. #5
    Frenzied Member the182guy's Avatar
    Join Date
    Nov 2005
    Location
    Cheshire, UK
    Posts
    1,473

    Re: Send winsock messages issue

    Quote Originally Posted by CVMichael
    That's because you are not waiting for the command to complectly send and you are sending another command, and of course, since Winsock is sending data by Streamming, all data is appended.
    It's as if you are sending one big string.

    Take this example:
    You send the following data
    client.SendData ("#MOVE")
    client.SendData ("#AED")
    client.SendData ("#ENDMOVE")

    Remember that it takes time for the data to send.
    There is no waiting in between each SendData, so this is what hapens:

    First this executes (this is an example, an assumption on how it works):
    client.SendData ("#MOVE")
    winsock starts sending data
    It sends "#", buffer is "MOVE"
    it sends "M", buffer is "OVE"
    it sends "O", buffer is "VE"
    Since there is no wait, it executes the next line
    client.SendData ("#AED")
    buffer is now "VE#AED"
    it sends "V", buffer is "E#AED"
    it sends "E", buffer is "E#AED"
    it sends "#", buffer is "AED"
    Since there is no wait, it executes next line
    client.SendData ("#ENDMOVE")
    buffer is now "AED#ENDMOVE"
    it sends "A"
    it sends "E"
    and so on until buffer is empty

    What happends on the client side in the mean time ?
    It received data, one byte at the time, and bufferes it.
    The winsock will raise the event when 2 things happen:

    1) Buffer reaches it's max, about ~4000 bytes
    OR
    2) It's time-out is reached ~ 100 ms (lets say, I don't know the actual time-out)

    So... now you can see why you receive the data all concatenated...

    Since your message is short, you won't reach 4000 bytes to triger the DataArrival event, and also, since the data is short, it will send pretty fast, and it's shorter than the time-out

    Therefore, you get the whole thing as one "#MOVE#AED#ENDMOVE"

    How to fix it ?

    When you send data, you have to wait for the SendComplete event, and then issue the next "SendData".

    But of course since your program has to wait for the SendComplete event, the actual sending of the data is slower.
    The SendComplete event gets trigered when the send buffer is empty.

    What can you do ?

    1) Don't use TCP/IP protocol, use the UDP protocol, it will send the data right away, regardless of how much data (as long as it's less than max buffer ~ 4000 bytes).

    2) Live with it, expect the data to arrive concatenated.
    Since data is concatenated, encapsulate the data in headers, it will still be concatenated, but at least you will know when one packet ends, and the other starts.
    In this particular case, you can search for the "#" character.

    lol ???????? or just send it like this...

    VB Code:
    1. TCP.SendData ("#Move")
    2. [B]DoEvents[/B]
    3. TCP.SendData ("#Something")
    4. [B]Doevents[/B]
    5. TCP.SendData ("#LOL")
    6. [B]DoEvents[/B]

    that will ensure the data is sent in individual packets not as one string.

    you dont have to 'live with it' nor do you have to use UDP, UDP is a completely different protocol, all that is required is DoEvents
    Chris

  6. #6

    Thread Starter
    Junior Member
    Join Date
    Apr 2006
    Posts
    25

    Re: Send winsock messages issue

    Great the DoEvents works like I need. However, sometimes my commands come in out of order (assuming it is due to threading when the msgs are sent). Is there a slick way to ensure my commands come in order? I thought about putting in a timer that goes off every ms or something, and then sends something new, but that seems to be the brute force way. Thoughts?

  7. #7
    Lively Member dastudios's Avatar
    Join Date
    Feb 2006
    Posts
    72

    Re: Send winsock messages issue

    why not use my example then, and stick a doevents in senddata (the subroutine)?

  8. #8
    PowerPoster
    Join Date
    Feb 2002
    Location
    Canada, Toronto
    Posts
    5,794

    Re: Send winsock messages issue

    Quote Originally Posted by the182guy
    lol ???????? or just send it like this...

    VB Code:
    1. TCP.SendData ("#Move")
    2. [B]DoEvents[/B]
    3. TCP.SendData ("#Something")
    4. [B]Doevents[/B]
    5. TCP.SendData ("#LOL")
    6. [B]DoEvents[/B]

    that will ensure the data is sent in individual packets not as one string.
    I thought you know better than this...

    DoEvents may raise other problems later during the development, and when you do have the problem, it will be very difficult to see the source of it is because of DoEvents...

    DoEvents is just a "quick fix" here...

    Let's see how laughs last ?

  9. #9
    Frenzied Member
    Join Date
    Aug 2000
    Location
    O!
    Posts
    1,177

    Re: Send winsock messages issue

    Quote Originally Posted by CVMichael
    I thought you know better than this...

    DoEvents may raise other problems later during the development, and when you do have the problem, it will be very difficult to see the source of it is because of DoEvents...

    DoEvents is just a "quick fix" here...

    Let's see how laughs last ?
    And, depending on conditions on the receiving end, the strings may still end up being concatenated in the receive buffer.

    IMHO, the best approach would be something like the event-driven code that dastudios provided.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width