Difference between revisions of "InSim examples"
From LFS Manual
Jump to navigationJump to searchm |
|||
| (7 intermediate revisions by 3 users not shown) | |||
| Line 5: | Line 5: | ||
How to connect, send a packet and receive the response. | How to connect, send a packet and receive the response. | ||
| − | <big><pre># | + | <big><pre># Dependencies. |
import socket | import socket | ||
| + | import struct | ||
| + | |||
| + | # Some constants. | ||
| + | INSIM_VERSION = 4 | ||
| + | BUFFER_SIZE = 2048 | ||
| − | # | + | # Packet types. |
| − | + | ISP_ISI = 1 | |
| + | ISP_VER = 2 | ||
| + | ISP_TINY = 3 | ||
| + | TINY_NONE = 0 | ||
| − | # | + | # Initailise the socket in TCP mode. |
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | ||
| Line 17: | Line 25: | ||
sock.connect(('localhost', 29999)) | sock.connect(('localhost', 29999)) | ||
| − | # Pack the | + | # Pack the ISI packet into a string. |
| − | isi = struct.pack(' | + | isi = struct.pack('BBBBHHBBH16s16s', |
| − | 44, | + | 44, # Size |
| − | + | ISP_ISI, # Type | |
| − | + | 1, # ReqI - causes LFS to send an IS_VER. | |
| − | 0, | + | 0, # Zero |
| − | 0, | + | 0, # UDPPort |
| − | 0, | + | 0, # Flags |
| − | 0, | + | 0, # Sp0 |
| − | + | 0, # Prefix | |
| − | 0, | + | 0, # Interval |
| − | 'password', | + | 'password', # Admin |
| − | ' | + | '^3example') # IName |
| − | + | ||
| − | # Send the | + | # Send the ISI packet to InSim. |
sock.send(isi) | sock.send(isi) | ||
| − | |||
buffer = '' | buffer = '' | ||
while True: | while True: | ||
| − | + | data = sock.recv(BUFFER_SIZE) | |
| − | data = sock.recv( | ||
| − | |||
| − | |||
if data: | if data: | ||
| − | |||
buffer += data | buffer += data | ||
| − | + | ||
| − | # Loop through | + | # Loop through completed packets. |
| − | |||
| − | |||
while len(buffer) > 0 and len(buffer) >= ord(buffer[0]): | while len(buffer) > 0 and len(buffer) >= ord(buffer[0]): | ||
| + | |||
# Copy the packet from the buffer. | # Copy the packet from the buffer. | ||
packet = buffer[:ord(buffer[0])] | packet = buffer[:ord(buffer[0])] | ||
| + | buffer = buffer[ord(buffer[0]):] | ||
| + | |||
| + | # Check packet type. | ||
| + | if ord(buffer[1]) == ISP_TINY: | ||
| + | # Unpack the TINY packet and check it for keep-alive signal. | ||
| + | size, type, reqi, subt = struct.unpack('BBBB', packet) | ||
| + | if subt == TINY_NONE: | ||
| + | sock.send(packet) # Respond to keep-alive. | ||
| + | elif ord(buffer[1]) == ISP_VER: | ||
| + | # Unpack the VER packet and check the InSim version. | ||
| + | size, type, reqi, _, version, product, insimver = struct.unpack('BBBB8s6sH') | ||
| + | if insimver != INSIM_VERSION: | ||
| + | break # Invalid version, break loop. | ||
| + | else: | ||
| + | break # Connection has closed. | ||
| + | |||
| + | # Release the socket. | ||
| + | sock.close()</pre></big> | ||
| + | |||
| + | = Visual C# = | ||
| + | |||
| + | == Example #1 == | ||
| − | + | How to connect, send a packet and receive the response. | |
| − | + | ||
| + | <big><pre>using System; | ||
| + | using System.Collections.Generic; | ||
| + | using System.Net; | ||
| + | using System.Net.Sockets; | ||
| + | using System.Text; | ||
| + | |||
| + | class Program | ||
| + | { | ||
| + | enum PacketType | ||
| + | { | ||
| + | ISP_ISI = 0, | ||
| + | ISP_VER = 1, | ||
| + | ISP_TINY = 2, | ||
| + | } | ||
| + | |||
| + | enum TinyType | ||
| + | { | ||
| + | TINY_NONE = 0, | ||
| + | } | ||
| + | |||
| + | const int BufferSize = 2048; | ||
| + | const int InSimVersion = 4; | ||
| + | |||
| + | static void Main() | ||
| + | { | ||
| + | // Initailise the Socket and connect to InSim. | ||
| + | Socket sock = new Socket( | ||
| + | AddressFamily.InterNetwork, | ||
| + | SocketType.Stream, | ||
| + | ProtocolType.Tcp); | ||
| + | sock.Connect("localhost", 29999); | ||
| + | |||
| + | // Create the ISI packet. | ||
| + | byte[] isi = new byte[44]; | ||
| + | isi[0] = 44; // Size | ||
| + | isi[1] = (byte)PacketType.ISP_ISI; // Type | ||
| + | isi[2] = 1; // ReqI | ||
| + | isi[3] = 0; // Zero | ||
| + | isi[4] = 0; // UDPPort | ||
| + | isi[5] = 0; // UDPPort | ||
| + | isi[6] = 0; // Flags | ||
| + | isi[7] = 0; // Flags | ||
| + | isi[8] = 0; // Sp0 | ||
| + | isi[9] = (byte)'!'; // Prefix | ||
| + | isi[10] = 0; // Interval | ||
| + | isi[11] = 0; // Interval | ||
| + | ASCIIEncoding.ASCII.GetBytes("password", 0, 8, isi, 12); // Admin | ||
| + | ASCIIEncoding.ASCII.GetBytes("^3Example", 0, 9, isi, 28); // IName | ||
| + | |||
| + | // Send the packet to InSim. | ||
| + | sock.Send(isi); | ||
| + | |||
| + | // Packet buffer. | ||
| + | List<byte> buffer = new List<byte>(); | ||
| + | |||
| + | while (true) | ||
| + | { | ||
| + | // Receive data from socket. | ||
| + | byte[] data = new byte[BufferSize]; | ||
| + | int received = sock.Receive(data); | ||
| + | if (received > 0) | ||
| + | { | ||
| + | // Add the data to the packet buffer. | ||
| + | byte[] temp = new byte[received]; | ||
| + | Array.Copy(data, temp, received); | ||
| + | buffer.AddRange(temp); | ||
| + | |||
| + | // Loop through all packets in the buffer. | ||
| + | while (buffer.Count > 0 && buffer.Count >= buffer[0]) | ||
| + | { | ||
| + | // Copy packet from buffer. | ||
| + | byte[] packet = new byte[buffer[0]]; | ||
| + | buffer.CopyTo(0, packet, 0, buffer[0]); | ||
| + | buffer.RemoveRange(0, buffer[0]); | ||
| + | |||
| + | // Check packet type. | ||
| + | if (PacketType.ISP_TINY == (PacketType)buffer[1]) | ||
| + | { | ||
| + | // Unpack TINY and respond to keep-alive. | ||
| + | byte size = packet[0]; | ||
| + | PacketType type = (PacketType)packet[1]; | ||
| + | byte reqi = packet[2]; | ||
| + | TinyType subt = (TinyType)packet[3]; | ||
| + | |||
| + | if (subt == TinyType.TINY_NONE) | ||
| + | { | ||
| + | sock.Send(packet); | ||
| + | } | ||
| + | } | ||
| + | else if (PacketType.ISP_VER == (PacketType)buffer[1]) | ||
| + | { | ||
| + | // Unpack VER and check InSim version. | ||
| + | byte size = packet[0]; | ||
| + | PacketType type = (PacketType)packet[1]; | ||
| + | byte reqi = packet[2]; | ||
| + | byte zero = packet[3]; | ||
| + | string version = ASCIIEncoding.ASCII.GetString(packet, 4, 8); | ||
| + | string product = ASCIIEncoding.ASCII.GetString(packet, 12, 6); | ||
| + | ushort insimver = BitConverter.ToUInt16(packet, 18); | ||
| + | |||
| + | if (insimver != InSimVersion) | ||
| + | { | ||
| + | break; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | // Connection has closed. | ||
| + | break; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // Release the socket. | ||
| + | sock.Close(); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | </pre></big> | ||
| − | # | + | = PHP = |
| − | # | + | == Example #1 == |
| − | + | <big><pre><?php | |
| − | + | $InSim = new InSim(); | |
| + | class InSim { | ||
| + | function __construct($AdminPass = '', $Address = '127.0.0.1', $Port = 29999, $PreFixChar = '!') { | ||
| + | // Socket In; | ||
| + | if ($this->skIn = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP)) { | ||
| + | echo('Listen socket created!' . PHP_EOL); | ||
| + | if (socket_bind($this->skIn, $Address, $Port + 1)) | ||
| + | echo('Binded to listen socket!' . PHP_EOL); | ||
| + | else | ||
| + | die('Could not bind to listen socket, address or port!' . PHP_EOL); | ||
| + | } else | ||
| + | die('Could not create listen socket!' . PHP_EOL); | ||
| + | |||
| + | // Socket Out; | ||
| + | if ($this->skOt = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP)) { | ||
| + | echo('Send socket created!' . PHP_EOL); | ||
| + | if (socket_connect($this->skOt, $Address, $Port)) | ||
| + | echo('Conneceted to send socket!' . PHP_EOL); | ||
| + | else | ||
| + | die('Could not connect to send socket, address or port!' . PHP_EOL); | ||
| + | } else | ||
| + | die('Could not create send socket!'); | ||
| + | |||
| + | # Connect To InSim; | ||
| + | $this->send(pack('CCCxSSxCSa16a16', 44, 1, 1, $Port + 1, 4 | 8, 36, 0, $AdminPass, 'phpInSim')); | ||
| + | $this->main(); | ||
| + | } | ||
| + | function send($packet) { | ||
| + | return socket_write($this->skOt, $packet, strlen($packet)); | ||
| + | } | ||
| + | function main() { | ||
| + | while (TRUE) { | ||
| + | # Keep Alive; | ||
| + | if (time() > $this->time) { | ||
| + | $this->send(pack('CCCC', 4, 3, 0, 0)); | ||
| + | $this->time = time() + 30; | ||
| + | } | ||
| + | # Get Packet; | ||
| + | if ($data = $this->recv()) { | ||
| + | print_r($data); | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | function recv() { | ||
| + | return socket_read($this->skIn, 256, PHP_BINARY_READ); | ||
| + | } | ||
| + | function __destruct() { | ||
| + | $this->send(pack('CCCC', 4, 3, 0, 2)); | ||
| + | } | ||
| + | } | ||
| + | ?></pre></big> | ||
| − | + | [[Category:InSim]] | |
Latest revision as of 00:59, 2 December 2023
Python
Example #1
How to connect, send a packet and receive the response.
# Dependencies.
import socket
import struct
# Some constants.
INSIM_VERSION = 4
BUFFER_SIZE = 2048
# Packet types.
ISP_ISI = 1
ISP_VER = 2
ISP_TINY = 3
TINY_NONE = 0
# Initailise the socket in TCP mode.
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Connect to LFS.
sock.connect(('localhost', 29999))
# Pack the ISI packet into a string.
isi = struct.pack('BBBBHHBBH16s16s',
44, # Size
ISP_ISI, # Type
1, # ReqI - causes LFS to send an IS_VER.
0, # Zero
0, # UDPPort
0, # Flags
0, # Sp0
0, # Prefix
0, # Interval
'password', # Admin
'^3example') # IName
# Send the ISI packet to InSim.
sock.send(isi)
buffer = ''
while True:
data = sock.recv(BUFFER_SIZE)
if data:
buffer += data
# Loop through completed packets.
while len(buffer) > 0 and len(buffer) >= ord(buffer[0]):
# Copy the packet from the buffer.
packet = buffer[:ord(buffer[0])]
buffer = buffer[ord(buffer[0]):]
# Check packet type.
if ord(buffer[1]) == ISP_TINY:
# Unpack the TINY packet and check it for keep-alive signal.
size, type, reqi, subt = struct.unpack('BBBB', packet)
if subt == TINY_NONE:
sock.send(packet) # Respond to keep-alive.
elif ord(buffer[1]) == ISP_VER:
# Unpack the VER packet and check the InSim version.
size, type, reqi, _, version, product, insimver = struct.unpack('BBBB8s6sH')
if insimver != INSIM_VERSION:
break # Invalid version, break loop.
else:
break # Connection has closed.
# Release the socket.
sock.close()
Visual C#
Example #1
How to connect, send a packet and receive the response.
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
class Program
{
enum PacketType
{
ISP_ISI = 0,
ISP_VER = 1,
ISP_TINY = 2,
}
enum TinyType
{
TINY_NONE = 0,
}
const int BufferSize = 2048;
const int InSimVersion = 4;
static void Main()
{
// Initailise the Socket and connect to InSim.
Socket sock = new Socket(
AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
sock.Connect("localhost", 29999);
// Create the ISI packet.
byte[] isi = new byte[44];
isi[0] = 44; // Size
isi[1] = (byte)PacketType.ISP_ISI; // Type
isi[2] = 1; // ReqI
isi[3] = 0; // Zero
isi[4] = 0; // UDPPort
isi[5] = 0; // UDPPort
isi[6] = 0; // Flags
isi[7] = 0; // Flags
isi[8] = 0; // Sp0
isi[9] = (byte)'!'; // Prefix
isi[10] = 0; // Interval
isi[11] = 0; // Interval
ASCIIEncoding.ASCII.GetBytes("password", 0, 8, isi, 12); // Admin
ASCIIEncoding.ASCII.GetBytes("^3Example", 0, 9, isi, 28); // IName
// Send the packet to InSim.
sock.Send(isi);
// Packet buffer.
List<byte> buffer = new List<byte>();
while (true)
{
// Receive data from socket.
byte[] data = new byte[BufferSize];
int received = sock.Receive(data);
if (received > 0)
{
// Add the data to the packet buffer.
byte[] temp = new byte[received];
Array.Copy(data, temp, received);
buffer.AddRange(temp);
// Loop through all packets in the buffer.
while (buffer.Count > 0 && buffer.Count >= buffer[0])
{
// Copy packet from buffer.
byte[] packet = new byte[buffer[0]];
buffer.CopyTo(0, packet, 0, buffer[0]);
buffer.RemoveRange(0, buffer[0]);
// Check packet type.
if (PacketType.ISP_TINY == (PacketType)buffer[1])
{
// Unpack TINY and respond to keep-alive.
byte size = packet[0];
PacketType type = (PacketType)packet[1];
byte reqi = packet[2];
TinyType subt = (TinyType)packet[3];
if (subt == TinyType.TINY_NONE)
{
sock.Send(packet);
}
}
else if (PacketType.ISP_VER == (PacketType)buffer[1])
{
// Unpack VER and check InSim version.
byte size = packet[0];
PacketType type = (PacketType)packet[1];
byte reqi = packet[2];
byte zero = packet[3];
string version = ASCIIEncoding.ASCII.GetString(packet, 4, 8);
string product = ASCIIEncoding.ASCII.GetString(packet, 12, 6);
ushort insimver = BitConverter.ToUInt16(packet, 18);
if (insimver != InSimVersion)
{
break;
}
}
}
}
else
{
// Connection has closed.
break;
}
}
// Release the socket.
sock.Close();
}
}
PHP
Example #1
<?php
$InSim = new InSim();
class InSim {
function __construct($AdminPass = '', $Address = '127.0.0.1', $Port = 29999, $PreFixChar = '!') {
// Socket In;
if ($this->skIn = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP)) {
echo('Listen socket created!' . PHP_EOL);
if (socket_bind($this->skIn, $Address, $Port + 1))
echo('Binded to listen socket!' . PHP_EOL);
else
die('Could not bind to listen socket, address or port!' . PHP_EOL);
} else
die('Could not create listen socket!' . PHP_EOL);
// Socket Out;
if ($this->skOt = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP)) {
echo('Send socket created!' . PHP_EOL);
if (socket_connect($this->skOt, $Address, $Port))
echo('Conneceted to send socket!' . PHP_EOL);
else
die('Could not connect to send socket, address or port!' . PHP_EOL);
} else
die('Could not create send socket!');
# Connect To InSim;
$this->send(pack('CCCxSSxCSa16a16', 44, 1, 1, $Port + 1, 4 | 8, 36, 0, $AdminPass, 'phpInSim'));
$this->main();
}
function send($packet) {
return socket_write($this->skOt, $packet, strlen($packet));
}
function main() {
while (TRUE) {
# Keep Alive;
if (time() > $this->time) {
$this->send(pack('CCCC', 4, 3, 0, 0));
$this->time = time() + 30;
}
# Get Packet;
if ($data = $this->recv()) {
print_r($data);
}
}
}
function recv() {
return socket_read($this->skIn, 256, PHP_BINARY_READ);
}
function __destruct() {
$this->send(pack('CCCC', 4, 3, 0, 2));
}
}
?>