Readline and streams

BlitzMax Forums/BlitzMax Programming/Readline and streams

Rambo_Bill(Posted 2005) [#1]
I can make readline never return depending on what I'm reading. Is this a bug or is there someway to check to see if a line is available?
I've put the code below, the part thats iffy is the part labeled with the big @@@ comment. Note: I have found work arounds, so for me it's not a big deal.




Tibit(Posted 2005) [#2]
It might me that no end-of-line is found before the TCP stream is out-of-bytes? Try ReadString so that you can control the length more precise.

Also you can use SocketReadAvail() which returns the number of bytes that can be read. Then read that amount.

Ex:

Global WebSock:tSocket ' our lovely socket
Global WebStream:tSocketStream ' our lovely stream
Global TheURL:String=""
Global EndRequest:String="0"

Global SessionCookie:String="" ' cookie for saving web session

Local TXT:String,TXT2:String=""
Connect("www.google.com")
Request("")

TXT = PollData(1000)
While TXT<>""
	TXT2=TXT2+ TXT
	TXT = PollData(1000)
Wend
Print "Closing"
Close()
Print "Done"

	
' connect to server
	Function Connect(sURL:String,iTimeOut:Int=5000)
		TheURL=sURL
		WebSock=CreateTCPSocket()
		ConnectSocket(WebSock,HostIp(sURL),80)
		iTimeOut = iTimeOut + MilliSecs()
		While Not SocketConnected(WebSock) 
			If MilliSecs()>iTimeOut Then
				Return 0 ' failed due to timeout
			End If
		Wend
     ' We are Connected, create our streamer
		WebStream=CreateSocketStream(WebSock,False)
		Return 1 ' success
	End Function
	
' Requests data from web server
	Function Request(sPage:String)
		Local TXT:String
		Local NL:String= Chr(13) + Chr(10)
		EndRequest=""
		' Form a HTTP 1.1 Get Request
		TXT="GET /" + sPage + " HTTP/1.1" + NL
		TXT=TXT + "Host: " + TheURL + NL
		TXT=TXT + "User-Agent: BlitzBrowser" + NL
		TXT=TXT + "Accept: */*" + NL
		'TXT=TXT + "Content-Length: 0" + NL
		If SessionCookie<>"" Then
			TXT = TXT + SessionCookie + NL
		End If
		WriteLine WebStream, TXT
		FlushStream(WebStream)
	End Function
' Poll for incoming data	
	Function PollData:String(sTimeOut:Int=1)
		Local TXT:String="",TXT2:String=""
		sTimeOut =sTimeOut+MilliSecs()
		While sTimeOut>MilliSecs() 
			'==================================
			' @@@ IS THIS A BUG -- SHOULD THIS HANG ?????
			'==================================

			Length = SocketReadAvail(WebSock)
			If Length > 0
				Print "Calling Readline"
				TXT = ReadString(WebStream,Length)'ReadLine(WebStream)
				
				If Len(TXT)>0 Then TXT2=TXT2 + TXT + Chr(13) + Chr(10)
				' if no cookie 
				If SessionCookie="" Then
						If Instr(TXT,"Set-Cookie",1)>0 Then
							If Not Instr(TXT,"n/a")>0 Then
								SessionCookie=Replace(TXT,"Set-Cookie","Cookie")
						End If
						End If
				End If
			EndIf	
		Wend
		Print "Exit PollData()"
		Return TXT2
	End Function
' Close Connection
	Function Close()
		SessionCookie=""
		CloseStream(WebStream)
		CloseSocket(WebSock)
	End Function


Do you have to use readline? I'm not sure what the result should be, but it does read something from google =) So it works that way.

A code TIP:
TXT = TXT + "Some String"
Can be written as:
TXT:+ "Some String"


Rambo_Bill(Posted 2005) [#3]
SocketReadAvail() sounds very promising, try it tonight when I get home. Thanks


Rambo_Bill(Posted 2005) [#4]
SocketReadAvail helped alot. Here is my newest code,but only works with sites that use content-length (Appears most do not)




Tibit(Posted 2005) [#5]
Cool! Really cool! So now I can see how my browser sees it. Are you doing a real browser or did you have something else in mind suchs as highscore/stats online?

I can't get it to work on sub sites, www.yahoo.com/mail
while yahoo.com works and also sub domains like movies.yahoo.com.


Tibit(Posted 2005) [#6]
Wait I don't get the full body on yahoo.. guess that's what not works.

Is the code public? Can I use it in TNet for html:highscore?


Rambo_Bill(Posted 2005) [#7]
Yep, its public domain code, otherwise I wouldn't post it. I am working on an encryption scheme that works with it which I won't share though.

To make it work with yahoo/google or any site that uses the chunk method, you would have to look for chunk-encoding (or something like that) in the header. It looks like when a server is using chunking that it gives you the length of each chunk at the beginning of the body. I don't need to support that for my site, but feel free to modify the code to support it, shouldn't be too hard. I'm going to use this for two way communications between my programs and my server. That's why it was important to maintain a session id. It shall work nicely I think.