We would like to build a community for Small Basic programmers of any age who like to code. Everyone from total beginner to guru is welcome. Click here to register and share your programming journey!


Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
TCP/IP Socket Programming
#11
Thanks a lot for your Help, the connection to the device is running now !!! Now i want to transmit a message of 13 Bytes with the function : LDClient.SendMessage() But i am not sure what the correct format of the message is ? I tryed LDClient.SendMessage("0030500000000") and LDClient.SendMessage(0030500000000) , but i am even not sure , wether this is the right way of doing it anyway ....... once more i need a little help from you .....
Reply
#12
Hi,

Glad the basic connection is working.

LDClient.SendMessage can take either a number or a string as input.  The input is then converted into a string, then array of bytes (each byte is the ascii character code value) with trailing null terminator before sending.

I would recommend sending a string so it is clear what you are sending, e.g.  LDClient.SendMessage("0030500000000").  If you send just a number LDClient.SendMessage(0030500000000) it would be interpreted as "3050000000" - conversion from number to string would loose the leading zeros.  This is the extension code behind SendMessage.

Code:
                if (!tcpClient.Connected) return "NOT_CONNECTED";
                Byte[] bytes = Encoding.UTF8.GetBytes(message + '\0');
                NetworkStream networkStream = tcpClient.GetStream();
                networkStream.Write(bytes, 0, bytes.Length);
                return "SUCCESS";

Secondly, you say you want to send bytes - there is a distiction between byte values and their ascii representation.  A byte is a number between 0 and 255 (in decimal and FF in hex), and each value represnets a character, so the character "0" is 48 (dec) or 30 (hex), see https://www.ascii-code.com.  If you want to send pure byte numbers then you will have to form the string using Text.GetCharacter(code), where code is the byte value.

Code:
char = Text.GetCharacter(48)
TextWindow.WriteLine(char)
code = Text.GetCharacterCode("0")
TextWindow.WriteLine(code)

One suggestion is to try to read from the server first (if you know how to get it to send a message), and see what it looks like.  

Code:
result = LDClient.Connect("192.168.2.20:15730", "False")
If (result = "SUCCESS") Then
  msg = ""
  LDClient.ServerMessage = OnServerMessage
  While("True") 'Keep the program running - we would do more here later
    If (msg <> "") Then 'We have a message
      TextWindow.WriteLine("Client message received : "+msg)
      msg = "" 'Message handled
    EndIf
   
    Program.Delay(10)' Don't mash cpu
  EndWhile
EndIf
Sub OnServerMessage
  msg = LDClient.LastServerMessage
EndSub


If you have a link to some documentation for the server device that you can share, there may be more detailed info on the data format required and some way to check what was received by the server.
[-] The following 1 user Likes litdev's post:
  • AbsoluteBeginner
Reply
#13
you are right with the conversion to ascii when the LDClient.SendMessage converts all to a string. so when i want to transmit a pure
00 (HEX) the LDClient.SendMessage send 30(Hex ) , that is the wrong value in the telegram for the device .
The Functions : Text.GetCharacter() or Text.GetCharacterCode(0) will not help me with that...... i guess . I think i have a problem now ;-(
Reply
#14
No, you can create a string of bytes of any value 0 to FF (hex)

Code:
bytes = ""
bytes = Text.Append(bytes,Text.GetCharacter(48))
bytes = Text.Append(bytes,Text.GetCharacter(0))
bytes = Text.Append(bytes,Text.GetCharacter(32))
bytes = Text.Append(bytes,Text.GetCharacter(7))
TextWindow.WriteLine(":"+bytes+":")
LDClient.SendMessage(bytes)

This is a string with bytes (dec) equal to 48, 0, 32, 7

When we print it, 48 is intepreted as chatracter 0, 0 is unprintable, 32 is a space, 7 is a machine beep

Also you can easily convert hex to decimal:

TextWindow.WriteLine(LDMath.Base2Decimal("ff",16))

EDIT

Something like this:

Code:
data = "0 0 3 0 5 0 0 CB 0 0 0 af 0" 'A space separated list of hex bytes
GetBytes()
LDClient.SendMessage(bytes)

Sub GetBytes
  dataArray = LDText.Split(data," ")
  bytes = ""
  For i = 1 To Array.GetItemCount(dataArray)
    codeHex = dataArray[i]
    codeDec = LDMath.Base2Decimal(codeHex,16)
    TextWindow.WriteLine("Byte "+i+" Hex="+codeHex+" Dec="+codeDec)
    char = Text.GetCharacter(codeDec)
    bytes = Text.Append(bytes,char)
  EndFor
EndSub
Reply
#15
LDClient.SendMessage(bytes)

Sub GetBytes
dataArray = LDText.Split(data," ")
bytes = ""

Hello, i understand the example, but how works ..... bytes = "" ..... ? how comes the converted result from ....dataArray.... into .... bytes .... ?
Reply
#16
Hi, not sure which bit you don't follow.

A string is in fact just an array of characters, so we can create a string by appending characters to the end of a string, this is what ' bytes = Text.Append(bytes,char) ' is doing.

So char is a single character.

A character is internally stored as a byte (00 to FF in hex), so a string as an array of bytes.  When we print a string, the char (byte) value corresponds to the character defined by the ascii code for the given byte value, so a string with byte value of 0x20 (or 32 decimal) will print a space.  Not all of the 256 ascii values are characters, some are control characters (originally derived from typewriters and mechanical input, like Line Feed, Cariage Return, Backspace, Beep etc.

So the key is to get the character (char) that corresponds to a given ascii code number, that is simply what '  Text.GetCharacter(7) ' does (7 is a machine beep).

So in the end we form a string (array of bytes) with each byte being the byte value corresponding to a character obtained from a byte value (in decimal, so we use the hex to decimal conversion '  LDMath.Base2Decimal ' for convenience).

Hope this helps.
Reply
#17
In posting #14:
bytes="" is used to clear the string before starting to append the chars.
[-] The following 2 users Like WhTurner's post:
  • litdev, z-s
Reply
#18
Hello, I send you a protocol of the wireshark sniffer tool.   I send from  169.254.22.62 ( my PC ) with 
 
LDClient.Connect( "169.254.5.166:15471" , "False" ) a Connection Command to my Device. 

The Response  was :

4 0.010297 169.254.5.166 169.254.22.62 TCP 66 15471 → 59024 [SYN, ACK] Seq=0 Ack=1 Win=29200 Len=0 MSS=1460 SACK_PERM
5 0.010505 169.254.22.62 169.254.5.166 TCP 54 59024 → 15471 [ACK] Seq=1 Ack=1 Win=131328 Len=0
6 0.010940 169.254.22.62 169.254.5.166 TCP 54 59024 → 15471 [RST, ACK] Seq=1 Ack=1 Win=0 Len=0

In Line 6 the PC send a RST , i think that mean "Reset"  to my Device  169.254.5.166 .....
Can you explain why this happens ?

The Protocol is in Attachment.


Attached Files Thumbnail(s)
   
Reply
#19
Hi,

I don't know anything about the device you are connecting to, or what SB code you are using apart from the connect command.

I am guessing that you connect to some device, and I guess that 'wireshark sniffer tool' records network traffic - I've never heard of or used it.

It sees some traffic (line 6) and your question is this being sent by the connection?

This is a lot of guessing by me.  Under the hood the extension LDCLient.Connect calls this connection command:

https://learn.microsoft.com/en-gb/dotnet...ew=net-9.0

I don't know in detail exactly what this does at a low level.

Maybe this helps (a bit of googling) - looks like maybe the device was sent something it didn't understand (line5?), but I'm not an expert at all on TCP:

https://www.pico.net/kb/what-is-a-tcp-reset-rst/

Or

https://www.howtouselinux.com/post/tcp-flags

Maybe someone else here has some experience with low level TCP

EDIT, maybe the SB program ended and the connection was closed?
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)