As I mentioned in the comments the solution of using string to mount the package is wrong, because if you convert a number to string it will be treated as string by PHP then the int(40) that should occupy 4 bytes in memory will take 2 bytes as string '4' and '0'
You can use PHP’s pack / unpack functions to convert the information into byte array. Ai the arrays will have the sizes you are looking for, but you can still see that the array elements are int's and if you put it all together also will not be the result you seek.
<?php
$bMsg3 = array (
$at1 = 1,
$at2 = 2,
$at3 = 3,
$at4 = 4,
$at5 = 5,
$at6 = 6,
);
$bMsg3[$at1] = 32768; /* Inteiro = 4 bytes */
$bMsg3[$at2] = 'HelloWorld'; /* String = 10 bytes */
$bMsg3[$at3] = 123456; /* Inteiro = 4 bytes */
$bMsg3[$at4] = 789101; /* Inteiro = 4 bytets */
$bMsg3[$at5] = 123852; /* Float = 4 bytes */
$bMsg3[$at6] = 'teste'; /* String = 5 bytes */
/* Total: 31 bytes */
echo "<pre>";
var_dump(unpack("C*", pack("i", $bMsg3[$at1])));
var_dump(unpack("C*", $bMsg3[$at2]));
var_dump(unpack("C*", pack("i", $bMsg3[$at3])));
var_dump(unpack("C*", pack("i", $bMsg3[$at4])));
var_dump(unpack("C*", pack("i", $bMsg3[$at5])));
var_dump(unpack("C*", $bMsg3[$at6]));
Upshot:
array(4) {
[1]=>
int(0)
[2]=>
int(128)
[3]=>
int(0)
[4]=>
int(0)
}
array(10) {
[1]=>
int(72)
[2]=>
int(101)
[3]=>
int(108)
[4]=>
int(108)
[5]=>
int(111)
[6]=>
int(87)
[7]=>
int(111)
[8]=>
int(114)
[9]=>
int(108)
[10]=>
int(100)
}
array(4) {
[1]=>
int(64)
[2]=>
int(226)
[3]=>
int(1)
[4]=>
int(0)
}
array(4) {
[1]=>
int(109)
[2]=>
int(10)
[3]=>
int(12)
[4]=>
int(0)
}
array(4) {
[1]=>
int(204)
[2]=>
int(227)
[3]=>
int(1)
[4]=>
int(0)
}
array(5) {
[1]=>
int(116)
[2]=>
int(101)
[3]=>
int(115)
[4]=>
int(116)
[5]=>
int(101)
}
So one of the possible solutions is to convert everything to hexa and send this package on the network.
<?php
$bMsg3 = array (
$at1 = 1,
$at2 = 2,
$at3 = 3,
$at4 = 4,
$at5 = 5,
$at6 = 6,
);
$bMsg3[$at1] = 32768; /* Inteiro = 4 bytes */
$bMsg3[$at2] = 'HelloWorld'; /* String = 10 bytes */
$bMsg3[$at3] = 123456; /* Inteiro = 4 bytes */
$bMsg3[$at4] = 789101; /* Inteiro = 4 bytets */
$bMsg3[$at5] = 123852; /* Float = 4 bytes */
$bMsg3[$at6] = 'teste'; /* String = 5 bytes */
/* Total: 31 bytes */
echo "<pre>";
var_dump(unpack("H*", pack("i", $bMsg3[$at1])));
var_dump(unpack("H*", $bMsg3[$at2]));
var_dump(unpack("H*", pack("i", $bMsg3[$at3])));
var_dump(unpack("H*", pack("i", $bMsg3[$at4])));
var_dump(unpack("H*", pack("i", $bMsg3[$at5])));
var_dump(unpack("H*", $bMsg3[$at6]));
That will result in that, but to send you can join them all in a single string.
array(1) {
[1]=>
string(8) "00800000"
}
array(1) {
[1]=>
string(20) "48656c6c6f576f726c64"
}
array(1) {
[1]=>
string(8) "40e20100"
}
array(1) {
[1]=>
string(8) "6d0a0c00"
}
array(1) {
[1]=>
string(8) "cce30100"
}
array(1) {
[1]=>
string(10) "7465737465"
}
In C the package comes as an unsigned char, so we can have this example here to print the data. (using a small piece of the package)
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(void) {
unsigned char pacote[] = { 0x00, 0x80, 0x00, 0x00, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x57, 0x6f, 0x72, 0x6c, 0x64 };
struct pckt {
int a;
char b[10];
};
struct pckt *meu_pckt = (struct pckt*) pacote;
char n[11];
memcpy(n, meu_pckt->b, 10);
n[10] = '\0';
printf("%d\n", meu_pckt->a);
printf("%s\n", n);
return 0;
}
Must print:
32768
HelloWorld
to read a buffer with a certain size you must use
fgets($handle, $tamanho_do_buffer)
– Wallace Maxters
Take a look here: http://php.net/manual/en/function.socket-read.php
– Ivan Ferrer
But if you make the string occupy 4 bytes it will lose information because each letter represents 1 byte and in "stringTeste" will have 11 bytes
– Adir Kuhn
Note that at1 is an INTEGER and at3 is a FLOAT, both occupy 4 bytes. at2 is a string that occupies 11 bytes. However, by converting this to string, it should have a total of 19 bytes, right? The question is, how to convert the array to string, so that the string occupies 19 bytes? which is the total size of the array attributes.
– Vynstus
How could it be 31 bytes? you have 5 more bytes of
:
, that is to say,31+5 = 36
.– Jorge B.
I just put a better example.
– Vynstus
But if you compute the bytes of a string, each number counts as 1 character and not as an integer.
132768!='132768'
– Jorge B.
Exactly, this number 132768 is an integer and is different from '132768' which is a string. Because it is integer, it occupies 4 bytes, that is, any integer occupies 4 bytes.
– Vynstus
exactly, you said everything, converting everything to string will be string. What you can do is maybe convert everything to binary or hexadecimal. Maybe define a package structure (package frame)
– Adir Kuhn
Do you have any idea how I could convert into binary and put these binaries in the string? Because I need to put this data inside the string, with their respective sizes.
– Vynstus
take a look at the php pack function
– Adir Kuhn
When the socket receives
"42Hello24"
how does he decide whether to receive aint
, one string and anotherint
... or 2int
(4, 2) 2 string ("Hell", "o") and two moreint
??– pmg
@pmg When I receive this string in the C Program, which has a struct containing the same attributes in the sequence, I will copy the string’s memory block and play on the struct using the function memmove(args). For this reason I want each attribute to respect the size of its type in the string.
– Vynstus
@Adirkuhn did not find much information about the pack function, could describe how it works in a response?
– Vynstus
Why don’t you send the normal string and then deal with it in C?
– Jorge B.
It would take a lot more work than the solution I’m looking for, and the processes in the C program should be shorter, the time it takes php to create the message is no problem in my case. One thing personal, would you know why is printing a number 1 at the beginning of the string? q being it starts at 32768.
– Vynstus
@Adirkuhn I solved the problem using the Pack function. Thank you very much.
– Vynstus