TCP/IP Message Format
From QB64 Wiki
With the addition of QB64 specific commands came the addition of networking commands. This page details how things like ports, IP addresses and QB64 formatted messages can work using these custom programming commands.
Internet Protocol Addresses, or simply IP Addresses, are numbers given to every computer/server connected to the Internet. Everything connected to the Internet has one, and they are used to specify what you are trying to connect to. An example would be 18.104.22.168. Each number is one byte. All together, an IP can be called a LONG type since it is 4 bytes long, but it has no uses (QB64 Specific uses) in this form. The IP Configuration should be saved in a STRING variable in the format displayed above (4 byte values separated by '.'). The command that uses IP addresses (_OPENCLIENT) uses IP addresses in string, so the IP Address will be able to be used in STRING format. It should be noted that a website name (“www.qb64.net” for example), for all intensive purposes, is the same as a IP Address. QB64 will do the conversion for you in an _OPENCLIENT command (If you want more info on this process, Google “DNS”).
IP Addresses can be expanded into three 'groups'. The first group, Global, includes all IP Addresses that belong to computers outside of your network. In general terms, most IP's are Global. Unless you're connecting to a computer/server that's connected under the same router as you, you'll have to use there Global IP to connect to them. The second group, Local, includes the IP Addresses of all the computers inside your network. It should be noted that all computers in the same network have the same Global IP. When connecting to computers in the same network as you, you HAVE to use their local IP. If you're connected to a router, then you'll have both a Global and Local IP. Use the Global one when computers are connecting from outside your routers network and the Local IP for computers connecting inside your network. The third group can be referred to as your Loopback address, specifically 127.0.0.1. This IP Address is used to connect back to your computer. Such as if you did the command _OPENHOST(“TCP/IP:234”) to open a host on port 234 (More on that down below). If you wanted to then connect a client from my computer to that host, you could do the command _OPENCLIENT(“TCP/IP:234:127.0.0.1”).
As to figuring out what your local/Global IP's are, there are a few things you can do. To get you're local, the easiest way is the command line. For windows, you can use the command 'ipconfig', and find the line labeled “IP” or “IPv4”. The IP Address listed after that is your local IP.(Note: If you're not hooked in to the Internet though a network but directly hooked into your modem you won't have a local IP. The IP Address listed there will be your Global IP). For Linux users, you can use the command “/sbin/ifconfig -a”. The response will be a little more cryptic. You will have to know what interface you're using for your Internet (eth0, wlan0, etc.). Scroll through the output to your interface and find the line 'inet addr:'. The IP Address after this is your Local IP. Acquiring your Global IP is easier, and not platform specific. Simply goto the website: http://www.whatsmyip.net/ and it will tell you.
Alternatively, for QB64 versions of the above examples, you can SHELL out the commands shown above, and gather the Local IP from the out put. For getting your Global IP, use _CONNECTIONADDRESS(host&) to get a string in the form of: “TCP/IP:PortNumber:GlobalIP”. (host& = _OPENHOST(“TCP/IP:PortNumber”)).
Port numbers are used in both the _OPENCLIENT and _OPENHOST commands. Port number are actually very simple. To communicate on the Internet, you have to use a port. All you really have to know about ports is that they are a number from 0 to 65535(_UNSIGNED INTEGER), and to have successful communication from one computer to another you have to be using the same port number.
The advantage of port numbers is you can have many communications going on at one time, each on a different port number. Such as I can have a chat server running on port 1065, and at the same time have another chat server running on port 1052. You should note that two programs can't be using the same port. If a program from outside of QB64 is using the same port as your program, your host/client will fail to open(This is why it's important to check for valid handles). If that's the case, inform the user of the program. The user will have to sort it out on there own. It's recommend you choose a high/random port number, as there are many many ports to choose from. Normally a port like 6242, 2523, etc. would be open.
For Linux users, only the root user can open hosts on ports lower then 1024. For windows users, you may have to open a exception for your program in windows firewall (You should get a prompt about this when you startup your program.).
For all platforms, if running though a router, you may have to 'port forward' the specific port you're using to your computers local IP. This is router specific, so it's recommended to check with your router's manufacturer as for how to do this. 'port forwarding' simply means rerouting all data on a specific port to a computer in the network (Remember, every computer connected to a router has the same global IP. It's your routers job to reroute this data to a specific computer in the network).
For reference, some common ports and their uses are listed below:
Port Number Used for 21 FTP (File Transfer Protocol) 22 SSH (Secure Shell) 25 SMTP (Simple Mail Transfer Protocol) 53 DNS (Domain Name System) service 80 HTTP (Hypertext Transfer Protocol) 110 POP (Post Office Protocol) 143 IMAP (Internet Message Access protocol) 161 SNMP (Simple Network Management Protocol) 443 HTTPs (Hypertext Transfer Protocol with TLS or SSL security) Full list of TCP and UDP port numbers
QB64 Formatted Messages
- PRINT #... and INPUT #... send/receive data across a TCP/IP connection using formatted messages (as opposed to GET #... and PUT #... which stream raw data). Formatted messages contain the message data and a header automatically added by QB64 specifying other information about the message. The header format is unique to QB64. Knowledge of the specific header format is generally unnecessary for QB64 programmers but documented here for reference purposes. The message header format is compact and can be extended (if necessary) in the future. Non-QB64 users MUST be made aware of this format to use it!
[Description Flags] (1 byte) Always used [Length of Data] (1, 2 or 4 bytes) Only used when flagged [Data] Bytes of actual data sent
- Bits 0-2 hold a value from 0 to 7 indicating how the length of the message's data can be obtained as follows:
0 means... the data is 0 bytes in length and [length of data] is not used 1 means... the data is 1 byte in length and [length of data] is not used 2 means... the data is 2 bytes in length and [length of data] is not used 3 means... the data is 3 bytes in length and [length of data] is not used 4 means... the data is 4 bytes in length and [length of data] is not used 5 means... [length of data] is 1 unsigned byte holding the length of the data 6 means... [length of data] is 2 unsigned bytes holding the length of the data 7 means... [length of data] is 4 unsigned bytes holding the length of the data
- Bits 3-6 do not have to be read as they must be set to 0
- Bit 7 (the top bit) is set to indicate that the message is incomplete and requires the next/following message to be appended to this message. In this way a long message may be deliberately sent as smaller messages and reassembled. In the following example a$ and b$ are combined into a single message/string by use of a semi-colon:
PRINT #connect_handle, a$; PRINT #connect_handle, b$
- Depending on the value of bits 0-2 in [description flags] 'length of data' may or may not be used. If it is used its value indicates how many bytes of data are in the following message content. The size of 'length of data' may be 0, 1, 2 or 4 bytes.
- Contains the raw data (content) of the message.
- The PRINT # formatted header sent can be read by INPUT # and will return EOF(connect_handle) = 0 when the transfer is completed. EOF will return -1 while it is not completed.
- INPUT (TCP/IP statement), PRINT (TCP/IP statement) (formatted data)
- GET (TCP/IP statement), PUT (TCP/IP statement) (raw data)
- _OPENCLIENT, _OPENHOST
- _CONNECTED, _CONNECTIONADDRESS
- IP Configuration, WGET (HTTP and FTP file transfer)
- Email Demo, Inter-Program Data Sharing Demo
- Computer File Sharing Demo
- Downloading Files
- Web Page Download (Windows)