Lapsnaper TCP connection specification - c#

I am using Lapsnapper (a transponder timing system) running on Android.
Lapsnapper enables a TCP/IP server with which a connection can be made, to build a custom interface and get some other relevant data RE: the transponders etc from the system.
I do not understand the Lapsnapper tcp server specification.
I have done some tcp stuff before, but I am mostly a higher level programmer and to be honest I am a bit out of my depth with this raw TCP stuff.
The spec reads:
What I don't understand is how to "send" the tcp data?
I don't understand how 0x70, 0x17 equates to (6000) and 2 bytes...
The same goes for 0x13, 0x00, 0x00, 0x00 = 19 which the spec says should be 4 bytes, but a string of "19" is 2 bytes?
I am trying to understand what I am reading. Any help would be appreciated as I need to do quite a bit of comms to this server, and I want to understand what I am doing...
I have asked for help from lapsnapper support, but in the mean time I would like to learn something new as per the above.
What do I actually "send" on the TCP connection?
The spec says that I should expect a message back, but with my current implementation, a connection seems to be established, but I never receive anything back.
Response Message to expect:
My code:
(P.S This code block works if I do a simple connection to a SMTP server and I can do a basic connection with reply from said smtp server. I however never receive a reply when I try to talk to the Lapsnapper TCP server using the code below)
string lapSnapperIP = "10.0.0.131";
int lapsnapperPort = 9001;
string lapSnapperMessageID;
string lapsnapperLengthOfMessage;
string lapsnapperProductID;
string lapsnapperServerVersion;
string lapsnapperPasswordLength;
string lapsnapperPassword;
lapSnapperMessageID = "6000";
lapsnapperLengthOfMessage = "19"; //to implement
lapsnapperProductID = "50";
lapsnapperServerVersion = "100000";
lapsnapperPasswordLength = "4";
lapsnapperPassword = "1234";
string lapSnapperDataSend;
lapSnapperDataSend = lapSnapperMessageID + lapsnapperLengthOfMessage + lapsnapperProductID + lapsnapperServerVersion + lapsnapperPasswordLength + lapsnapperPassword;
s.Connect(lapSnapperIP, lapsnapperPort);
byte[] sendMessage = Encoding.UTF8.GetBytes(lapSnapperDataSend);
byte[] receiveBytes = new byte[256];
int i = 0;
string receivedMessage = "";
//send data
i = s.Send(sendMessage);
//receive data
i = s.Receive(receiveBytes); // (no reply here...)
receivedMessage = Encoding.UTF8.GetString(receiveBytes);
Thanks

Related

c# how to return a string from a client to a server in TCP and UDP

So in my client I am looking for a way to return how many times a background worker was run to a server. Here is the code section for the client:
}
public int searchcount = 1;
public void SL_Click(object sender, EventArgs e)
{
try
{
TcpClient tcpclnt = new TcpClient();
tcpclnt.Connect(RecieveIP.Text, 8001); // use the ipaddress as in the server program
MessageBox.Show("Connected");
Stream stm = tcpclnt.GetStream();
MessageBox.Show("Listening for information......");
byte[] bb = new byte[100];
int k = stm.Read(bb, 0, 100);
string atk = Encoding.UTF8.GetString(bb.AsSpan(0, k));
Console.WriteLine($"S Connected to attack server at IPv4 address {RecieveIP.Text} Attack command Received: {atk}. If command is g, attacking google. Y means attacking yahoo. A means attacking aol. Yo meants attacking youtube, and s is attacking spotify");//test
//if you want your check
//this will not work if your incoming data contains white space or other bytes that were converted.
if (atk == "g" || atk.Contains("g"))
MessageBox.Show("Recieved Command " + atk);
if (atk == "g")
{
MessageBox.Show("Google");
search.RunWorkerAsync();
On thought, I do have a string
public int searchcount = 1;
Which the background worker in question adds one to display to the person running the client how many times it was run.
Console.WriteLine("Since start: " + count++.ToString());
Is there a way to return the count++ string to the server via both TCP and UDP? Thanks.
TCP(socket) is a protocol that you can send packages both ways. Udp on the other hand is stateless, you can only send packages from client to server. You cant maintain UDP connections open and keep sending/receiving packages. That said, you can send packages from client to server using UDP if the server dont need to respond your package.
I'm really doing some resume on what tcp/udp protocols are and i really encourage you to read about them on MS official docs before using anything on production.
Here some TCP , UDP and sockets examples and documentation on MS official docs.
Tcp Client/Server
Udp Client/Server
Sockets

Why is Ruby sockets server working with other Ruby sockets client but not a C# sockets client?

So I have two Ruby programs, they are a client and server sockets programs and they work together exchanging messages. But a C# client does not work. I give MCVE, first the ruby client.
#socketClient.rb
#With thanks to https://code.likeagirl.io/socket-programming-in-ruby-f714131336fd
require "socket"
while sum = $stdin.gets.chomp # Read lines from the socket
socket = TCPSocket.open("localhost", 3000)
#puts "Starting the Client..................."
socket.puts sum
while message = socket.gets # Read lines from the socket
puts message.chomp
end
socket.close # Close the socket
end
#puts "Closing the Client..................."
and the server
#simplestSocketServer.rb
#With thanks to https://code.likeagirl.io/socket-programming-in-ruby-f714131336fd
require "socket"
port = 3000
ipAddress = "127.0.0.1"
server = TCPServer.open(ipAddress, port) # Server would listen on port 3000
loop { # Servers run forever
puts "Starting the Server, accepting connections on port " + port.to_s + "..................."
client_connection = server.accept # Establish client connect connection
begin
clientText = client_connection.gets.chomp
puts clientText
resp = "Acknowledged"
client_connection.puts("#{clientText}" + "#{resp}") # Send the answer to the client
client_connection.puts("Closing the connection with #{client_connection}")
rescue Exception => getException
puts "#{getException}"
end
client_connection.close # Disconnect from the client
}
and the C# console program
using System;
using System.Net.Sockets;
using System.Text;
namespace SimplestCSharpRubySocketsClient
{
class Program
{
static void Main(string[] args)
{
try
{
string ipAddress = "127.0.0.1";
Int16 portNumber = 3000;
TcpClient _client; _client = new TcpClient();
_client.Connect(ipAddress, portNumber);
System.Console.WriteLine("we have connected, seemingly ...");
NetworkStream stream;
stream = _client.GetStream();
Byte[] sendBytes = Encoding.UTF8.GetBytes("some text");
System.Console.WriteLine("writing and flushing some bytes ...");
stream.Write(sendBytes, 0, sendBytes.Length);
stream.Flush();
Byte[] recvBytes = new byte[_client.ReceiveBufferSize];
System.Console.WriteLine("_client.ReceiveBufferSize = " + _client.ReceiveBufferSize); // <--- this prints 65536
System.Console.WriteLine("waiting to read bytes ...");
stream.Read(recvBytes, 0, recvBytes.Length); //<--- hangs here
System.Console.WriteLine("comething came back ...");
string result = Encoding.UTF8.GetString(recvBytes);
string result2 = result.Substring(0, result.LastIndexOf("\r\n"));
_client.Close();
_client.Dispose();
_client = null;
}
catch (Exception ex)
{
//TODO figure out a better error handler
throw ex;
}
}
}
}
The C# program connects and writes bytes but when looking to read bytes it just hangs.
And be aware I am running the C# console program in Visual Studio with admin rights. The two ruby programs run in their own separate Windows console windows.
Folding in some feedback, I added another line in the ruby server to output the clientText. And it prints nothing, suggesting the server is not fully receiving the bytes. Is there a termination signal that C# is required to send?
Thanks in advance.
The problem here is that the C# client does not send a newline at the end of the string, like the Ruby version does (socket.puts sends a string with a newline at the end).
If you change your sendBytes array to include a \n in the payload like this:
Byte[] sendBytes = Encoding.UTF8.GetBytes("some text\n");
you will see that it prints comething came back ... on the console.
The newline is required because of the following gets in the Ruby server:
clientText = client_connection.gets.chomp

ZMQ recv randomly picks up garbage data does any one know why?

I have a client server app which is sending data from a C# client to a C++ server. When the server receives this data request, 9 out of 10 times it works ok, but there is always 1 time were there will be garbage data appended to the end of the received data on the server side.
for example instead of receiving a number 1 it will receive 1C or 1#????
Here are snippets of the client and server code, any help will be appreciated.
C# client
int flagSide = 1;
msg = name;
msg += "+";
msg += "qty";
msg += "+";
msg += flagSide.ToString();
ZeroMQ.ZmqContext context = ZeroMQ.ZmqContext.Create();
ZeroMQ.ZmqSocket socket = context.CreateSocket(SocketType.REQ);
socket.Connect("tcp://111.111.0.111:5556");
socket.Send(Encoding.ASCII.GetBytes(msg.ToCharArray()));
Thread.Sleep(1);
string reply = socket.Receive(Encoding.ASCII);
Console.WriteLine("Received reply = " + reply + "\n");
C++ Server
std::tr1::unordered_map <std::string, std::string> aMap;
zmq::context_t context( 1 );
zmq::socket_t responder( context, ZMQ_REP );
responder.bind ("tcp://*:5556");
while ( 1 )
{
zmq::message_t recvMsg;
responder.recv( &recvMsg );
t = static_cast<char*>( recvMsg.data() );
std::string s(t);
std::vector<std::string> strs;
boost::split(strs, s, boost::is_any_of("+"));
aMap["name"] = strs[0];
aMap["qty"] = strs[1];
aMap["flag"] = strs[2];
..........
outputing the split string in the server reveals that sometimes the flag or strs[2] receives the garbage data.
Please help me if you see something that I'm not seeing.
Thanks
In C#, strings converted to bytes are not null-terminated, and c++ string expects a null terminated pointer.
So I presume what is happening here, is a buffer underflow. You are reading memory which does not belongs to the string.

gsm ATD command to check my balance

I am trying to write a program that makes a phone call via bluetooth
and return my balance (money). I am using the 32feet.net bluetooth api.
BluetoothAddress addr = device.DeviceAddress;
BluetoothEndPoint rep = new BluetoothEndPoint(addr, BluetoothService.Handsfree);
BluetoothClient cli = new BluetoothClient();
cli.Connect(rep);
Stream peerStream = cli.GetStream();
String dialCmd4 = "ATD*100#;\r";
Byte[] sRes = new Byte[200];
Byte[] dcB = System.Text.Encoding.ASCII.GetBytes(dialCmd4);
peerStream.Write(dcB, 0, dcB.Length);
peerStream.Read(sRes, 0, 199);
string t4 = "\n\r----------\n\r" + System.Text.Encoding.ASCII.GetString(sRes);
peerStream.Close();
cli.Close();
This code make a regular call but doesn't return a message containing my balance,
and in the phone I can see this message "number not assigned".
Using ATD to send SS (supplementary service) USSD (Unstructured Supplementary Service Data) commands will in the very, very, very best case only work for a small subset (or not at all. When you enter those number using the MMI they are parsed by a completely different entity than the one parsing AT commands).
What you really want to do is to use those AT commands that have specifically been written to support sending SS or USSD. For USSD you use
AT+CUSD=[<n>[,<str>[,<dcs>]]]
See the 3GPP 27.007 specification for details.

C# need help debugging socks5-connection attemp

I've written the following code to (successfully) connect to a socks5 proxy.
I send a user/pw auth and get an OK reply (0x00), but as soon as I tell the proxy to connect to whichever ip:port, it gives me 0x01 (general error).
Socket socket5_proxy = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint proxyEndPoint = new IPEndPoint(IPAddress.Parse("111.111.111.111"), 1080); // proxy ip, port. fake for posting purposes.
socket5_proxy.Connect(proxyEndPoint);
byte[] init_socks_command = new byte[4];
init_socks_command[0] = 0x05;
init_socks_command[1] = 0x02;
init_socks_command[2] = 0x00;
init_socks_command[3] = 0x02;
socket5_proxy.Send(init_socks_command);
byte[] socket_response = new byte[2];
int bytes_recieved = socket5_proxy.Receive(socket_response, 2, SocketFlags.None);
if (socket_response[1] == 0x02)
{
byte[] temp_bytes;
string socks5_user = "foo";
string socks5_pass = "bar";
byte[] auth_socks_command = new byte[3 + socks5_user.Length + socks5_pass.Length];
auth_socks_command[0] = 0x05;
auth_socks_command[1] = Convert.ToByte(socks5_user.Length);
temp_bytes = Encoding.Default.GetBytes(socks5_user);
temp_bytes.CopyTo(auth_socks_command, 2);
auth_socks_command[2 + socks5_user.Length] = Convert.ToByte(socks5_pass.Length);
temp_bytes = Encoding.Default.GetBytes(socks5_pass);
temp_bytes.CopyTo(auth_socks_command, 3 + socks5_user.Length);
socket5_proxy.Send(auth_socks_command);
socket5_proxy.Receive(socket_response, 2, SocketFlags.None);
if (socket_response[1] != 0x00)
return;
byte[] connect_socks_command = new byte[10];
connect_socks_command[0] = 0x05;
connect_socks_command[1] = 0x01; // streaming
connect_socks_command[2] = 0x00;
connect_socks_command[3] = 0x01; // ipv4
temp_bytes = IPAddress.Parse("222.222.222.222").GetAddressBytes(); // target connection. fake ip, obviously
temp_bytes.CopyTo(connect_socks_command, 4);
byte[] portBytes = BitConverter.GetBytes(3333);
connect_socks_command[8] = portBytes[0];
connect_socks_command[9] = portBytes[1];
socket5_proxy.Send(connect_socks_command);
socket5_proxy.Receive(socket_response);
if (socket_response[1] != 0x00)
MessageBox.Show("Damn it"); // I always end here, 0x01
I've used this as a reference: http://en.wikipedia.org/wiki/SOCKS#SOCKS_5
Have I completely misunderstood something here? How I see it, I can connect to the socks5 fine. I can authenticate fine. But I/the proxy can't "do" anything?
Yes, I know the proxy works.
Yes, the target ip is available and yes the target port is open/responsive.
I get 0x01 no matter what I try to connect to.
Any help is VERY MUCH appreciated!
Thanks,
Chuck
You might be getting bitten by endianness. Is BitConverter.GetBytes returning you the right bytes, for instance? Did you step through it and check if your byte arrays contain what you expect them to?
That looks like little endian, and networking-related things usually use big endian. BitConverter always uses system endianness, so you'll have to reverse bytes by hand if you're running on a little endian system (which you would seem to be doing). BitConverter.IsLittleEndian will tell you whether your system is little endian or not.
Also, it'd be a good idea to cast your value to short, e.g. BigConverter.GetBytes((short)3333). That way you'll get just the two bytes you need.

Categories

Resources