TSocket/TSocketStream in banks

BlitzMax Forums/BlitzMax Beginners Area/TSocket/TSocketStream in banks

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

Thanks for the guides. I started to use types and this is the current code i've made:
Strict

Const RemoteFileCRLF:String = Chr(13) + Chr(10)
Const RemoteFileUserAgent:String = "Transporter"
Const RemoteFileTimeOut:Int = 5 * 1000

Type TRemoteFile
	Field url:String, port:Int
	Field filename:String, size:Int
	Field socket:TSocket, stream:TSocketStream
	Field error:String
	
	Function Open:TRemoteFile(url:String, port:Int = 80, postdata:String = "", header:String = "")
		Local file:TRemoteFile = New TRemoteFile
		
		Local protocol:String = Sector(url, ":", 0)
		Local host:String = Sector(url, "/", 2)
		Local path:String = "/" + Sector(url, "/", 3, True)
		
		' Check for port in server name
		If Instr(host, ":") Then
			port = Int(Sector(host, ":", 1))
			host = Sector(host, ":", 0)
		EndIf
		Local server:String = "www." + Sector$(host$, ".", Sectors%(host$, ".") - 1) + "." + Sector$(host$, ".", Sectors%(host$, "."))
		
		file.url = url
		file.port = port
		file.error = ""
		file.filename =  Sector(path, "/", Sectors(path, "/"))
		
		file.socket = CreateTCPSocket:TSocket()
		BindSocket(file.socket, 0)
		
		' Connect to server
		Local connection:Int = ConnectSocket(file.socket, HostIp(server), port)
		If Not connection Then connection:Int = ConnectSocket(file.socket, HostIp(host), port)
		
		If connection
			file.stream = CreateSocketStream:TSocketStream(file.socket)
			
			Select protocol
				Case "http"
					Local txt:String = ""
					If Len(postdata) > 0 Then txt :+ "POST " + path + " HTTP/1.1" + RemoteFileCRLF Else txt :+ "GET " + path + " HTTP/1.1" + RemoteFileCRLF
					txt :+ "Host: " + host + RemoteFileCRLF
					txt :+ "User-Agent: " + RemoteFileUserAgent + RemoteFileCRLF
					If Len(header) > 0 Then txt :+ header + RemoteFileCRLF
					If Len(postdata) > 0 Then txt :+ "Content-Type: application/x-www-form-urlencoded" + RemoteFileCRLF + "Content-Length: " + Len(postdata) + RemoteFileCRLF
					txt :+ "Connection: Close" + RemoteFileCRLF
					txt :+ ""
					If Len(postdata) > 0 Then txt :+ RemoteFileCRLF + postdata
					WriteLine(file.stream, txt)
					
					Print txt
					
					' Check response
					Local tim:Int = MilliSecs()
					Repeat
						If RemoteReadAvail(file)
							txt = ReadRemoteLine(file)
							If Sector(txt, "/", 0) = "HTTP"
								If Int(Sector(txt, " ", 1)) => 303 Then file.error = "HTTP Error: " + txt
								Exit
							EndIf
						EndIf
						If (MilliSecs() - tim) => RemoteFileTimeOut Then file.error = "No response from server!"
					Forever
					
					Local cmd:String, value:String
					If file.error = ""
						Repeat
							If RemoteReadAvail(file)
								txt = ReadRemoteLine(file)
								If txt$ = "" Then Exit
								
								cmd = Sector(txt, ":", 0)
								value = Sector(txt, " ", 1)
								Select cmd
									Case ""
										Return file
									Case "Content-Disposition"
										Local i:Int, subtxt:String, subvalue:String
										For i = 0 To Sectors(value, ";")
											subtxt = Trim(Sector(value, ";", i))
											subvalue = Sector(subtxt, "=", 1)
											
											Select Lower(Sector(subtxt, "=", 0))
												Case "filename"
													file.filename = subvalue
											End Select
										Next
									Case "Content-Length"
										file.size = Int(value$)
								End Select
							EndIf
						Forever
					EndIf
				Case "ftp"
			End Select
		Else
			file.error = "Unable to connect to " + file.url + ":" + file.port
		EndIf
		
		Return file
	End Function
	
	Method ReadAvail:Int()
		Return SocketReadAvail(socket)
	End Method
	
	Method RemoteLine:String()
		Return ReadLine(stream)
	End Method
	
	Method LastError:String()
		Return error
	End Method
	
	Method Name:String()
		Return filename
	End Method
	
	Method FSize:Int()
		Return size
	End Method
End Type

Local file:TRemoteFile = OpenRemoteFile("http://www.rate.ee/")
If RemoteFileError(file) = ""
	While Not RemoteReadAvail(file)
	Wend
	
	While RemoteReadAvail(file)
		Print RemoteFileName(file) + " [" + RemoteFileSize(file) + "] "+ " -> " + ReadRemoteLine(file)
	Wend
Else
	Notify RemoteFileError(file)
EndIf
End

Function OpenRemoteFile:TRemoteFile(url:String, port:Int = 80, postdata:String = "")
	Return TRemoteFile.Open(url, port, postdata)
End Function

Function RemoteReadAvail:Int(file:TRemoteFile)
	Return file.ReadAvail()
End Function

Function ReadRemoteLine:String(file:TRemoteFile)
	Return file.RemoteLine()
End Function

Function RemoteFileError:String(file:TRemoteFile)
	Return file.LastError()
End Function

Function RemoteFileName:String(file:TRemoteFile)
	Return file.Name()
End Function

Function RemoteFileSize:Int(file:TRemoteFile)
	Return file.FSize()
End Function

Function Sector:String(txt:String, separator:String, sector:Int, toend:Int = 0)
	Local result:String = "", occ:Int, i:Int
	For i:Int = 1 To Len(txt)
		If Mid(txt, i, 1) = separator
			occ :+ 1
			If toend And occ > sector Then result = result + Mid(txt, i, 1)
		Else
			If occ => sector Then result = result + Mid(txt, i, 1)
		EndIf
		If Not toend Then If occ > sector Then Exit
	Next
	Return result
End Function

Function Sectors:Int(txt:String, needle:String)
	Local occ:Int = 0, i:Int
	For i:Int = 1 To Len(txt)
		If Instr(txt, needle, i)
			occ = occ + 1
			i = Instr(txt, needle, i)
		Else
			Exit
		EndIf
	Next
	Return occ
End Function


Function OpenRemoteFile:TRemoteFile(url:String, port:Int = 80, postdata:String = "") can be used to open a remote/online file. After that you'll need to check for errors: RemoteFileError:String(file:TRemoteFile) and then you can start to read with ReadRemoteLine:String(file:TRemoteFile)