![]() |
|
|||||||
| Home | Register | FAQ | Members List | Search | Today's Posts | Mark Forums Read |
| Questions & Help Needed Post any question regarding Basic4ppc. |
![]() |
|
|
LinkBack | Thread Tools | Display Modes |
|
|||
|
Still no success with your code.I just copied the timer part and it does not catch any data from the network, with the result, that my routine is exiting because the server did not respond the way it expected.
Furthermore i can't see the advantage of the timer here..if you issue a command against a server in a certain protocol language, you have to wait for the server's response because depending on the answer you will decide how to proceed.Even if the timer does catch the answer, it does not help as long as my routine does not wait for the answer, because it's crucial for further processing. If the task is to get a telnet server response into a command line style window, timing is not important and also the server's response doesn't matter, if there's no one who is waiting for a certain answer. Providing you've got a fast network connection...your timer has an interval of 500ms setup.So 500ms goes by, before the timer is activated the first time.Can you imagine, how long 500ms in terms of networks is...? Server connections with 500ms delay are supposed to be very high latency connections.The latency to my mail server is 8ms.So you never will catch up a server response unless you lower your timer interval. Beside this it appears like it takes far too long to start the timer the first time, whatever i use for the interval.I built in a function printing out something within the timer code.This does come up after my routine exited for "long" time. So, for me and at this time only works to retrieve the server's reponse right after i sent the command to server and this only, if i strip of the client.DataAvailable thingy. This looks then like this: Code:
Sub asub
...
s = "a command against the server"
netwritebuffer() = bit.StringToBytes(s,0,StrLength(s))
stream.WriteBytes(netwritebuffer())
...
GetServerResponse()
if expected response then
...
do the next command
...
end if
no success
End Sub
...
Sub GetServerResponse
'If client.DataAvailable Then
Dim bufferbits(4096) As byte
count = stream.ReadBytes(bufferbits(),4096)
buf = bit.BytesToString(bufferbits(),0,count)
Return buf
' End If
End Sub
So this looks more complicated as it appears to look.I personally don't think the client.DataAvailable does not work, rather i think it has to do with timing.Can you explain me, what advantage the use of a timer has in that case, given the fact that the "sender part" has to wait for the response anyhow..? For me that looks this way: i setup a timer that polls something and i poll then, if the timer got already the result..? This makes no sense, and given the fact that the timer does not run in parallel it makes even less sense...? Usually this would be handled this way: .. Send something setup callback: wait for network response & call me as soon as result is available at CB_resume go to sleep...zzz..zzzz..zzzz .. CB_resume: Yas i got an answer and can proceed ... So for now i'm a little bit confused and need investigate this further...any suggestions..? cheers TWELVE |
|
||||
|
Check this link Network "library" for another example of a client/server example using timers and DataAvailable. Start an instance on your desktop as a server, start aother as a client and they should talk to each other. One thing to note is the loop on DataAvailable in the timer loop, you still get the timer latency but once data starts arriving you suck it all out before exiting.
|
|
|||
|
Hello Erel & agraham,
i did further testing and was successful in getting my code working, but..I'm still having issues with the client.DataAvailable. I was able to get this here to work: Code:
Sub MySub
...
send something to the server
GetNetworkResponse
make a decision depending on buf
...
End Sub
Sub GetNetworkResponse
Do Until client.DataAvailable = true
Sleep(300)
Loop
Dim bufferbits(4096) As byte
count = stream.ReadBytes(bufferbits(),4096)
buf = bit.BytesToString(bufferbits(),0,count)
Return buf
End Sub
So far so good.But if i change the time in Sleep() to more than 300, the program will deadlock within the Loop.This is because the client.DataAvailable never becomes true.You mentioned above, that the time does not matter for this function.So i could - theoretically - execute client.DataAvailable at the end of my program and would get back a true ( yes there's data i received from the server) and could then retrieve this data - if the server ever responded someting. So..why does my code above not work anymore if the sleep() is set higher than 300...? I do not have an explanation for that, do you..? If i add a counter, which exits the loop after a certain number of cycles, everything works ok: Code:
Sub GetNetworkResponse
x=1
buf = ""
Do Until client.DataAvailable = true
Sleep(500)
x = x+1
If x > 50 Then
Return
End If
Loop
Dim bufferbits(4096) As byte
count = stream.ReadBytes(bufferbits(),4096)
buf = bit.BytesToString(bufferbits(),0,count)
Return buf
End Sub
To circumvent that problem, i use then this code : Code:
x=1
buf = ""
Do While buf = ""
x = x+1
' If x > 20 Then
' Return
' End If
Dim bufferbits(4096) As byte
count = stream.ReadBytes(bufferbits(),4096)
buf = bit.BytesToString(bufferbits(),0,count)
Sleep(500)
Loop
Return buf
end sub
It just reads the buffer in a loop, until the buffer (buf) is different from an empty string.To prevent a deadlock from happening, if there is no answer from the server, i built in the If...then which is ending the loop after a certain number of cycles. So i assume then: data.ClientAvailable is working in general, but sometimes it does not.I suspect it happens when the retrieved server response is not complete yet. This would the look like this: i send some request data to the server ( netwritebuffer() = bit.StringToBytes(s,0,StrLength(s)) ) after 100ms i check client.DataAvailable client.DataAvailable is true ==> i retrieve the server response the server is sending more response data after 100ms i check client.DataAvailable client.DataAvailable is false If i rely on the client.DataAvailable ==> loop is infinite now if i just retrieve the data, the buffer contains what i was looking for. This probably happens, if the delay betweens checks is shorter than the server needs to send the complete answer.Since i cannot know the server's response time in advance and i don't know, if the server has completed its answer, i have either to check, if i can expect more data from server or i have to set a time out, after which i will give up waiting. For this, i've to rely on the client.DataAvailable or i can do a cyclic stream.ReadBytes until i get a non-empty string or the timeout is reached. Therefore my guess is, client.DataAvailable does indicate the first data received after a netwritebuffer(), but if the server sends more packets after the first data ( which was indicated by client.DataAvailable) had been retrieved using stream.ReadBytes, any subsequent reply packet is then not indicated by the the client.DataAvailable any more. I took now the first code example, added the cycle count check as a timeout and complemented the Do Until..Loop check with "OR (buf <> "")", which prevents the code from running unnecessary loops passes: Code:
Sub GetNetworkResponse
x=1
buf = ""
Do Until client.DataAvailable = true OR (buf <> "")
Sleep(500)
x = x+1
If x > 50 Then
Return
End If
Loop
Dim bufferbits(4096) As byte
count = stream.ReadBytes(bufferbits(),4096)
buf = bit.BytesToString(bufferbits(),0,count)
Return buf
End Sub
@Erel: please can you have a look at this behavior, why the client.DataAvailable does not indicate subsequent packets from the server, while i can read them anyhow..? regards TWELVE |
|
||||
|
I don't know why it doesn't work with Sleep > 300.
DataAvailable checks whether there is data waiting in the network buffer. Writing and reading from the network stream is a blocking operation. When you try to read from the stream the program is blocked until data arrives. It is possible that DataAvailable returns false and still you can read from the stream (which will cause a small internal waiting). I'm not sure you should use DataAvailable at all in your case. If you expect to receive a message after sending one you should just read from the stream. Remember that the server socket can also get blocked waiting for you to read the first message. |
|
||||
|
This is my Sub from a Request/Response app that has been running for months on several different computers and OSs. We have noticed that different computers seem to suffer from different numbers of timeouts which we have up to now put down to network problems as the server is situated in a cottage overlooking the Irish Sea with ADSL delivered over overhead phone lines subject to salt spray and so whose connections can be a little iffy. It normally sleeps for 50mS between checks but I have just tried 500mS and 1000mS and it works fine first time, but my computer always does. I don't have access to the other computers that appear to need several retries most of the time.
Maybe these differences are due to something like this DataAvailable problem. I've looked with Reflector and the DataAvailable call ends up calling the native OS ioctlsocket() function to get the number of bytes available to read from the socket. I can't look any deeper than that. Code:
Sub NetGetData(req)
msg ="An error occurred connecting to " & URL
ErrorLabel("err2")
Client.New1
Client.Connect(URL, Port)
Stream.New1(Client.GetStream,true)
msg = "GET /" & req & " HTTP/1.1" & Crlf
msg = msg & "Host: " & URL & Crlf
msg = msg & "Proxy-Connection: Keep-Alive" & Crlf
msg = msg & "Pragma: no-cache" & crlf
If Secure Then
p = StringToBase64(User & ":" & password)
msg = msg & "Authorization: Basic " & p & Crlf
End If
msg = msg & Crlf
WebReq() = Stream.StringToBytes(msg)
Stream.WriteBytes2(WebReq(),0,StrLength(msg))
Timer = 0
Do
Sleep(SleepMs)
Timer = Timer + SleepMs
If Timer >= Timeout Then
Return "A timeout occurred communicating with " & Device
End If
Loop Until Client.DataAvailable = true
count = Stream.ReadBytes(WebResp(),4096)
msg = Stream.BytesToString (WebResp(), 0, Count)
Client.Close
If SubString(msg, 13,2) = "OK" Then
msg = SubString(msg, 44, StrLength(msg)-44)
Else
msg = "Badly formatted data received from " & Device
End If
err2:
If ChkDebug.Checked Then
Msgbox(msg,"Message data received")
End If
Return msg
End Sub
|
|
||||
|
Hello TWELVE!
My english is not as good, that I can understand everything of your thread, but I think, you have a simular problem, that I have. Perhaps, you have a look at my thread: Read NMEA from Server I haven't found an answer for my problem until today, but I also have noticed, that client.dataavailable is affected from the timerinterval. Do you know, how i can eliminate a lock up of my application, when the server sends no data? You have experienced a lot and you have perhaps found some answers to avoid the problem. Thanks a lot.... ![]() |
![]() |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| One server adn more clients | Byak@ | Questions & Help Needed | 2 | 08-12-2008 11:59 AM |
| connectio tcpIP telnet protocol | mircome | Questions & Help Needed | 2 | 06-22-2008 12:16 PM |
| Read NMEA from Server | schimanski | Questions & Help Needed | 42 | 05-13-2008 09:42 AM |
| New server | Erel | Forum Discussion | 12 | 11-06-2007 05:21 PM |