Solved

Winsock SendData Problem

Posted on 2003-11-27
25
1,245 Views
Last Modified: 2013-11-13
Dear anyone who could help me,
     I am trying to use the method "SendData" of Winsock Control to submit the data to the server. However, I found the problem that although I submitted the different line of code for the statement "SendData" but these messages was concatenated into a single string and the server has got the incorrect message.
     For easily to understand, I would give you a brief code as following
Private Sub Command1_Click
     Winsock1.SendData "Merging"
     ............................................
     Winsock1.SendData "Merged"
End Sub
     I expected that the server should get 2 messages, "Merging" and "Merged". But in fact, I found that the server has got only a message "MergingMerged" and the server program works in the wrong way.
     Does anyone ever met this problem before and how to solve it ?
                                                                          Meng
0
Comment
Question by:prasitlee
  • 10
  • 6
  • 2
  • +5
25 Comments
 
LVL 48

Expert Comment

by:AlexFM
ID: 9831364
Try to send 0 in the end of each string:

dim b as BYTE
b = 0

Winsock1.SendData "Merging"
Winsock1.SendData b
Winsock1.SendData "Merged"
Winsock1.SendData b
0
 
LVL 142

Expert Comment

by:Guy Hengel [angelIII / a3]
ID: 9831411
What you see as 2 lines in your code will send a small amount of data to the server, which in fact will be nothing else than a stream of data arriving. As the amount you showed is small enough to be part of 1 network packet, it will in fact be transmitted as 1 packet as it is submitted.
You need to ensure with any means that on the server you know to "split" the lines as intended, by inserting special characters (like Alex shows above) or even complete sequences of data, for example the vbCrLf (Carriage return Line feed).
On the server's DataArrival() method, you need to ensure that the symbol 0 or vbCrLf has arrived to determine how to split the data, while this also helps you to determine if the data is complete.

CHeers
0
 
LVL 6

Author Comment

by:prasitlee
ID: 9831413
Dear AlexFM,
   It showed me only message "Merging" but the message "Merged" was gone. The server does not  receive this message.
                                                                  Meng
0
 
LVL 6

Author Comment

by:prasitlee
ID: 9831435
Dear angelIII,
    The program, I wrote, needed to know when the client submits "Merging" and when the client submits "Merged". The server will execute the different line of code due to the different message submitted to the server. The time and its duration is the important factor of this program.
                                                                           Meng
0
 
LVL 142

Expert Comment

by:Guy Hengel [angelIII / a3]
ID: 9831540
>>The program, I wrote, needed to know when the client submits "Merging" and when the client submits "Merged"
You have to know that what you see is that both messages are send so fast one after the other that they in fact arrive at the "same time", ie together. If you wait some time between the senddata() calls, you will see that they arrive seperately.
Using 0 as separator will not help in your problem to get 2 different events, but will only help to split the data on the server side. In fact, the "Merging" has NOT gone, but will not be displayed by the debug.print for example because of the character 0. If you display character by character of the data string arrived, you will "see" that.

CHeers
0
 
LVL 6

Author Comment

by:prasitlee
ID: 9831568
Dear angelIII,
    Actually I need my server program to set a flag variable after getting the message "Merging". The process, that is running on the server during "Merging" , is different with the process during "Merged".
    How could we control the packet to send only "Merging" and not wait for the other messages until the packet is full ?
                                                                                      Meng
0
 
LVL 6

Author Comment

by:prasitlee
ID: 9831579
Dear angelIII,
    Do you know how long does the packet store the information for submitted through the network ? I might change my message to be long enough to be only one in a packet.
                                                                             Meng
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 9831600
On the server side read data into Byte array and not directly into the string. When data is received, mobe it byte-by-byte into the string. If byte = 0, handle this string and start filling the next string.
Socket connection is byte-oriented, and you should provide some code which parses the byte sequence and extracts messages from it. In your case, you get the following sequence on the server side:

Merging\0Merged\0

You can also decide to use another symbol like delimiter.
0
 
LVL 142

Expert Comment

by:Guy Hengel [angelIII / a3]
ID: 9831615
>Do you know how long does the packet store the information for submitted through the network ?

This will depend on the underlying network technology, if compression is used etc... You should NOT try to rely on these things, better assume that if 2 messages arrive together, they are submitted at "almost" the same time.
You could add the current time from the client to the message as additional information...

CHeers
0
 
LVL 6

Author Comment

by:prasitlee
ID: 9831620
Dear AlexFM,
    Try to read my comment. I have already told that the time the message arrived is matter. I could not receive all the message at the same time and process as your comment. It is too late to do.
                                                                  Meng
0
 
LVL 6

Author Comment

by:prasitlee
ID: 9831662
Dear AngelIII,
    Actually I told you all wrong, the time is not matter. But the important thing is the program which is running on the server.
    I would give you more details about it.
    After the message was submitted, the server started to do some tasks. Once the server got the message "Merging", it would change the way to execute the process. Finally the server got the message "Merged", it was reminded that the merging process is done and change the way to execute to the normal code not special condition.
    Hopefully you would understand me clearly.
                                                                                       Meng
0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 142

Expert Comment

by:Guy Hengel [angelIII / a3]
ID: 9831927
Thus, as mentionned above:
* you have to split the data arrived as by the delimiters, and set the "server" settings as desired
* if the 2 messages arrive that fast so they arrive at the same time, you server will not really have the time to switch between both modes...

CHeers
0
 
LVL 2

Expert Comment

by:MaxPol
ID: 9831934
Hi,

here I think, you should take case of some more info.

Winsock is handling message exchange between systems. If the system is waiting for that message, than it will take it, if not, the message will be lost.

As a sample, if A send a message to B and B is not "Listening" for messages, then the message will be lost.

Now a normal way to work is like a Browser/Web Server implementation.

The Web Server is always in Listening by default. Whenever a browser "request" (senddata) a particular page, the Web Server will connect to this webbroser and get this message (getdata).
The Browser will then wait for some data to come back (up to a specified time-out).

So in your case, you should try to understand how your server part is working.

Another example could be a POP3 mail server.

The server is always Linstening.

When a connection occour, he will wait for messages. (below a sample of the normal communication for a POP3 server):

CLIENT will send 'USER Donald' and wait for a reply             The SERVER is waiting for a message: receive USER Donald
                                                                                       The SERVER will send OK and wait for a reply
CLIENT get the OK and send PASS duck                               The SERVER will get the password, authenticate the user
                                                                                       and reply with OK or ERR if not authenticated

So, your application should do something similar.

SendData "Merging" & vbcrlf
Doevents ' this is always required after a senddata!!!

in DataArrival should wait for any reply the server will send to say OK, I received (or any info will send after he will finish the job)
validate the data arrived. It will probably send something like OK, I received, so I start merging or after merging will send OK, data merged, here are the data.

At this point you could send againg the next data and so on....

Hope this help,

Max



0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 9832308
Whenever you use the SendData() method, you do actually get told when the send is complete.  It comes in the form of an event called "SendComplete".  You just need to wait for the event to fire before moving on to the next command.  The code below shows you one way to do this.

Regards,

Idle_Mind

' Code Follows...
Private sendComplete As Boolean

Private Sub sendSomeData()
    sendComplete = False
    Winsock1.SendData "some command" & vbCrLf
    Do While Not sendComplete
        DoEvents
    Loop
    sendComplete = False
    Winsock1.SendData "another command" & vbCrLf
    Do While Not sendComplete
        DoEvents
    Loop
End Sub

Private Sub Winsock1_SendComplete()
    sendComplete = True
End Sub
0
 
LVL 3

Expert Comment

by:Basker
ID: 9855025
I have come across the problem before, The problem is Winsock in VB queues up the messages until it has much enough to send it.

So what you can try is use the Setsockopt api function with  the SND_BUF argument,

Add this code

Const SO_SNDBUF = &H1001&     ' Send buffer size.
Const SOL_SOCKET = 65535      ' Options for socket level.

Private Declare Function setsockopt Lib "wsock32.dll" (ByVal s As Long, ByVal level As Long, ByVal optname As Long, optval As Any, ByVal optlen As Long) As Long

Before you connect or listen to the socket, just put

Setsockopt(winsock1.sockethandle,SOL_SOCKET,SO_SNDBUF,1,4)

Make sure that the variable you try to send in Senddata is  a string of size 1024

This will work,
0
 
LVL 6

Author Comment

by:prasitlee
ID: 9859482
Dear all,
    Thank you for all of your effort that put to help me solve my problem. Anyway it seems that I could not control this submission of the package to the network via Winsock Control.
     However, at the present time, I solve this problem myself by writing a file in a PC to let the program know what the actual status is. It is the easy solution for myself in the case I am working on the single machine.
     The main reason I need to use Winsock because I need to know the way to solve this problem. In the future, I may need to face the same situation again but on the real network environment not the single machine as I face now.
     Thank you so much for all of your effort. Anyway if anyone know the better way than these comments. Please do not hesitate to post your comment to share this knowledge to the others.
                                                                            Meng
0
 
LVL 1

Expert Comment

by:Lycaon
ID: 9897071
The problem is that the Winsock controll buffers all received data until you call a .GetData...  If your client sends two different strings fast enough, they both are stuck in the revceiving Winsock's buffer until your server uses .GetData.

The easiest way to get around this is to use your own buffer, of sorts.  If your server receives more than one message in a .GetData, then the buffer, and a few lines of code, will help process a single message at a time.

' Client program
Sub Whatever()

Winsock.SendData "Merging" & vbCrLf

' Do stuff

Winsock.SendData "Merged" & vbCrLf

End Sub

' -----------------------------

' Server
Sub Winsock_DataArrival(bytesTotal As Long)
Static Buffer As String
Dim StrData As String, tmpWord As String

Winsock.GetData StrData

Buffer = Buffer & StrData

Do While InStr(1, Buffer, vbCrLf) <> 0 ' If you have received a vbCrLf then the entire word or phrase is there, so process it

tmpWord = Left(Buffer, InStr(1, Buffer, vbCrLf) + 1) ' Grab everything up to and including the vbCrLf

Buffer = Mid(Buffer, Len(tmpWord) + 1) ' Remove the current string from the Buffer

' If you want to remove the vbCrLf, uncomment the following line
' tmpWord = Left(tmpWord, Len(tmpWord) - 2)

MsgBox "Here is the first word/phrase: " & tmpWord

Loop

End Sub
0
 
LVL 6

Author Comment

by:prasitlee
ID: 9905007
Dear Lycaon,
    Thanks for your effort to find out the solution. Anyway I think you are misunderstanding my point.
    The point is how to immediately submit the message "Merging" and the server immediately got it. I don't want to submit "Merging" and "Merged" at the same time.
    If they are submitted at the same time, the server would execute the incorrect result to my database. The server is automatically executed everytime the database were changed. And I wish these events should ignore all results if they know that at the present time the program "Merging" is executed and they should return to the normal status if the program "Merging" is done after it send the message "Merged" to the server.
     Hopefully you would understand my point.
                                                                    Meng
0
 
LVL 142

Expert Comment

by:Guy Hengel [angelIII / a3]
ID: 9905159
prasitlee, I think the problem was very well understood by all of the above.
Now, I have some questions:
* why don't you use the database itself to store this "merging" status information in a dedicated table, and use that on the server to "ignore" all results during that time?

* are you aware that during your tests, the time between the first and the second time could indeed be very short, and thus the status changes very fast; and that in "real" environment, this might take indeed quite long time?

* are you aware that the proposals (to analyse the data on the server using some separator like "carriage return line feed") would indeed SOLVE your problem? You have to understand that if the 2 messages are indeed send in such a short time that they arrive together on the server, the server would change it's status also only for very short time!!!!

CHeers
0
 
LVL 6

Author Comment

by:prasitlee
ID: 9905299
Dear angelIII,

* why don't you use the database itself to store this "merging" status information in a dedicated table, and use that on the server to "ignore" all results during that time?

   Yes, that 's the similar I have told above that I find the solution myself by writing the status of "Merging" to a file and use the server program to read the status.

* are you aware that during your tests, the time between the first and the second time could indeed be very short, and thus the status changes very fast; and that in "real" environment, this might take indeed quite long time?

    I don't think the time is not short as you expected. I am writing a program to customize the event of "Creating Event", "Changing Event" and "Deleting Event".
    Each event would take some time for processing not a short time as you expected. That 's why the solution of writing file to show the status worked well with my program right now.

* are you aware that the proposals (to analyse the data on the server using some separator like "carriage return line feed") would indeed SOLVE your problem? You have to understand that if the 2 messages are indeed send in such a short time that they arrive together on the server, the server would change it's status also only for very short time!!!!

    I have tested a lot of way all experts suggested and I found that the Winsock control fire the event "GetData" only once although the client submit the message twice. That 's why I need to separate each of them from the client to let the server fire the event "GetData" for 2 times. The different time between each message is matter to my program.

     Hopefully you all would clear my intention.
                                                                             Meng
0
 
LVL 142

Expert Comment

by:Guy Hengel [angelIII / a3]
ID: 10162335
My suggestion: Refund and PAQ
0
 
LVL 6

Author Comment

by:prasitlee
ID: 10166596
Dear CleanupPing,
   I agree with angelIII.
                                                     Meng
0
 

Accepted Solution

by:
amp072397 earned 0 total points
ID: 10618981
PAQed, with points refunded (250)

Thanks very much!
amp, ee admin, amp*at*experts-exchange.com
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

Suggested Solutions

Have you ever wanted to restrict the users input in a textbox to numbers, and while doing that make sure that they can't 'cheat' by pasting in non-numeric text? Of course you can do that with code you write yourself but it's tedious and error-prone …
I was working on a PowerPoint add-in the other day and a client asked me "can you implement a feature which processes a chart when it's pasted into a slide from another deck?". It got me wondering how to hook into built-in ribbon events in Office.
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now