Basic4ppc - Windows Mobile Development  

Go Back   Basic4ppc - Windows Mobile Development > Main Category > Questions & Help Needed
Home Register FAQ Members List Search Today's Posts Mark Forums Read

Questions & Help Needed Post any question regarding Basic4ppc.


Comunicating with a Telnet Server


Reply
 
LinkBack Thread Tools Display Modes
  #11 (permalink)  
Old 05-02-2008, 01:33 AM
Knows the basics
 
Join Date: Apr 2008
Location: Duesseldorf, Germany
Posts: 71
Default

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
If i remove the ticks in front of client.DataAvailable and Endif, i never get the response ( even though i can see the correct response by the server in a network trace...) and therefore exit the 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
Reply With Quote
  #12 (permalink)  
Old 05-02-2008, 05:58 AM
Erel's Avatar
Administrator
 
Join Date: Apr 2007
Posts: 3,199
Default

After a connection is established between a client and a server no data can get lost.
It doesn't matter if you read the data immediately or not. The data is buffered.
If you try to read data before it arrived the process will be blocked until data arrives.

In the case of the ChitChat example the Timer and the DataAvailable check are required to prevent blocking.
You must use a timer or some other polling mechanism if you are checking DataAvailable.
Reply With Quote
  #13 (permalink)  
Old 05-02-2008, 09:10 AM
agraham's Avatar
Basic4ppc Expert
 
Join Date: Jul 2007
Location: Cheshire, UK
Posts: 1,770
Awards Showcase
Beta Tester Forum Contributer 
Total Awards: 2
Default

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.
Reply With Quote
  #14 (permalink)  
Old 05-05-2008, 01:40 AM
Knows the basics
 
Join Date: Apr 2008
Location: Duesseldorf, Germany
Posts: 71
Default

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
If the condition persists, the if..then needs to break the loop after the specified maximum number of loop cycles...and if this occurs, the buf has the correct server response stored.So the answer was there, but the client.DataAvailable prevent the loop from finishing, so it loops for ever.



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
Reply With Quote
  #15 (permalink)  
Old 05-05-2008, 07:06 AM
Erel's Avatar
Administrator
 
Join Date: Apr 2007
Posts: 3,199
Default

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.
Reply With Quote
  #16 (permalink)  
Old 05-05-2008, 09:31 AM
agraham's Avatar
Basic4ppc Expert
 
Join Date: Jul 2007
Location: Cheshire, UK
Posts: 1,770
Awards Showcase
Beta Tester Forum Contributer 
Total Awards: 2
Default

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
Reply With Quote
  #17 (permalink)  
Old 05-05-2008, 06:25 PM
schimanski's Avatar
Knows the basics
 
Join Date: Oct 2007
Location: Germany
Posts: 63
Default I think, thats my old problem!

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....
Reply With Quote
Reply



Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

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


All times are GMT. The time now is 06:05 AM.


Powered by vBulletin® Version 3.6.12
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO 3.1.0