Limit on TCP Stream or String?

BlitzMax Forums/BlitzMax Programming/Limit on TCP Stream or String?

Nexic(Posted 2007) [#1]
I'm attempting to do some networking and it seems as if Blitz is limiting the communications to 80 characters per line. I'm not sure whether it's some kind of limit on the strings, or the TCP stream I'm reading from.

The program is a relay between a client an a server that wouldn't normally be able to communicate, Blitz is translating. So it's acting as a client to one, and a server to another, and passing data between the two.

They are both definitely sending lines bigger than 80 characters, but when it gets to the other end it seems a newline has appeared in the middle.

If anyone knows why this might be happening or a way around it please let me know :)


SculptureOfSoul(Posted 2007) [#2]
Well, i know it's not a limitation of Blitz as I was sending much longer lines to and from my MUD server. Of course, I did forego using socket streams and instead used the raw sockets.

Unless you are using "WriteLine()" to send the data to and from client to server (since WriteLine() adds a return and newline) my guess would be that it's the TCP stream you're reading from. How is that data being sent - is it being transferred as ASCII characters or as a binary encoded packet?


Nexic(Posted 2007) [#3]
It's being sent as ASCII, in one case terminated by ~r~n, and ~0 in the other direction.


Here is the code for the main connection in both directions. I got this off of the code archives and modified it slihtly. I'm certain there is no way the extra newlines are being added anywhere else in the program. As you can see it uses WriteString and ReadString
Type TCPSocketConnection
	Field MyID:String
	Field MyServer:TCPSocketServer
	Field MySocket:TSocket
	Field MyStream:TSocketStream
	Field Buffer:String = ""
	Field StopSeq:String
	
	Function Create:TCPSocketConnection(s:TCPSocketServer, NewSocket:TSocket)
		Local c:TCPSocketConnection = New TCPSocketConnection
		c.MyServer = s
		c.MySocket = NewSocket
		c.MyStream = CreateSocketStream(c.MySocket)
		c.StopSeq = c.MyServer.StopSeq
		c.MyID = DottedIP(c.MySocket.RemoteIP())
		Return c
	End Function

	Method Send(Text:String)
		MyStream.WriteString(Text)
	End Method

	Method Receive:String()
		Local nBytes:Int = MySocket.ReadAvail()
		Local s:String = StopSeq
		If nBytes Then
			Local in:String = ReadString(MyStream, nBytes)
			
			Buffer:+ in
			If Buffer.Length >= s.Length And Right$(Buffer,s.Length) = s Then
				
				Local t:String = Buffer.Replace(s,"") 'Strip out the Stop sequence
				Return t
				
			 End If
			
		End If
	End Method
	
End Type



SculptureOfSoul(Posted 2007) [#4]
I think your problem is with the following line
If Buffer.Length >= s.Length And Right$(Buffer,s.Length) = s Then 


I'm assuming your stop sequence is either ~r~n or ~0, right? Well, the problem with that piece of code is that it's only comparing the end of the buffer to see if it matches the stop sequence. The thing is, the original message may be getting split into multiple packets such that your ~r~n or ~0 are ending up in the middle of the packet - therefore they'll be in the middle of your buffer and the above test will fail and the stop sequence won't be found or replaced.

Why don't you try changing the if to the following
If( Buffer.Find( StopSeq, 0 ) )

Local t:String = Buffer.Replace(s,"") 'Strip out the Stop sequence

Return t

End If


I might very well be wrong, but it's the only thing I can think of at the moment.


Nexic(Posted 2007) [#5]
Thanks for your help but after more probing I realised that it was actually the server not BlitzMax.


SculptureOfSoul(Posted 2007) [#6]
Cool, good to hear you've got that worked out.

It's still a good idea never to assume that you'll receive a full packet/message/string/whatever though, as that may not always be the case. ;)