|
Home > Archive > Unix Programming > July 2006 > How to send binary or hex data in Socket using C ?
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
How to send binary or hex data in Socket using C ?
|
|
|
| Hi,
I stopped programming for quite some time. And I really loose some
touch here..
How can I send a stream of hex representation of data and send it to a
socket ?
I'm trying to write some generic SMPP API via tcp socket. Most of the
SMPP types are either in 4 bytes int or char terminated by NULL byte.
So If I need to send "0x00000002 0x00000000 0x00000001" to the remote
socket, how should I write this using C ?
cheers
CT
| |
| Pascal Bourguignon 2006-07-17, 1:20 pm |
| "ctloh" <chitsung.loh@gmail.com> writes:
> Hi,
>
> I stopped programming for quite some time. And I really loose some
> touch here..
>
> How can I send a stream of hex representation of data and send it to a
> socket ?
>
> I'm trying to write some generic SMPP API via tcp socket. Most of the
> SMPP types are either in 4 bytes int or char terminated by NULL byte.
>
> So If I need to send "0x00000002 0x00000000 0x00000001" to the remote
> socket, how should I write this using C ?
IPC and network communications are defined in terms of bytes. You
send one byte, then the next, etc.
If you write that you need to send something like:
"0x00000002 0x00000000 0x00000001"
which is a string of characters, assuming ASCII we understand you want
to send the following bytes (in hexa):
unsigned char bytes[]={ 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x32, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x30, 0x78,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31 };
To send these bytes, you only need to use write(2), something like:
void write_buffer(unsigned char* bytes,int size){
while(size>0){
int res=write(remote_fd,ptr,size);
if(res<0){
switch(errno){
case EAGAIN: break;
case EINTR: break;
default: perror("write");exit(1);}}
else{
ptr+=res;
size-=res;}}}
write_buffer(bytes,sizeof(bytes));
But if what you really want to send is these 32-bit integers:
unsigned int words[]={0x00000002, 0x00000000, 0x00000001};
then you must first convert them to a byte sequence according to what
is specified by the protocol. In Network protocols, it's specified
that the most significant byte be sent first. You can convert an
integer to a MSBF byte sequence with:
unsigned char* serialize_unsigned_int(unsigned char* ptr,unsigned int value){
(*ptr)=(value>>24)&0xff; ptr++;
(*ptr)=(value>>16)&0xff; ptr++;
(*ptr)=(value>>8)&0xff; ptr++;
(*ptr)=value&0xff; ptr++;
return(ptr);}
then you can fill a byte buffer with the three integer values:
unsigned char bytes[sizeof(words)];
unsigned char* ptr=bytes;
for(i=0;i<sizeof(words)/sizeof(words[0]);i++){
ptr=serialize_unsigned_int(ptr,words[i]);}
write_buffer(bytes,ptr-bytes);
Of course, if the protocol specifies that the integer values must be
sent as text encoded in ASCII, you can just use sprintf:
unsigned char bytes[128];
int size=snprintf(bytes,sizeof(bytes),"0x%08x 0x%08x 0x%08x",2,0,1);
write_byffer(bytes,size); /* or size+1 if the terminating null must be sent */
--
__Pascal Bourguignon__ http://www.informatimago.com/
Our enemies are innovative and resourceful, and so are we. They never
stop thinking about new ways to harm our country and our people, and
neither do we. -- Georges W. Bush
| |
|
| Cool. Thanks dude.
Pascal Bourguignon wrote:
> "ctloh" <chitsung.loh@gmail.com> writes:
>
>
> IPC and network communications are defined in terms of bytes. You
> send one byte, then the next, etc.
>
> If you write that you need to send something like:
>
> "0x00000002 0x00000000 0x00000001"
>
> which is a string of characters, assuming ASCII we understand you want
> to send the following bytes (in hexa):
>
> unsigned char bytes[]={ 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
> 0x30, 0x32, 0x20, 0x30, 0x78, 0x30, 0x30, 0x30,
> 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x30, 0x78,
> 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31 };
>
> To send these bytes, you only need to use write(2), something like:
>
>
> void write_buffer(unsigned char* bytes,int size){
> while(size>0){
> int res=write(remote_fd,ptr,size);
> if(res<0){
> switch(errno){
> case EAGAIN: break;
> case EINTR: break;
> default: perror("write");exit(1);}}
> else{
> ptr+=res;
> size-=res;}}}
>
> write_buffer(bytes,sizeof(bytes));
>
>
> But if what you really want to send is these 32-bit integers:
>
> unsigned int words[]={0x00000002, 0x00000000, 0x00000001};
>
> then you must first convert them to a byte sequence according to what
> is specified by the protocol. In Network protocols, it's specified
> that the most significant byte be sent first. You can convert an
> integer to a MSBF byte sequence with:
>
> unsigned char* serialize_unsigned_int(unsigned char* ptr,unsigned int value){
> (*ptr)=(value>>24)&0xff; ptr++;
> (*ptr)=(value>>16)&0xff; ptr++;
> (*ptr)=(value>>8)&0xff; ptr++;
> (*ptr)=value&0xff; ptr++;
> return(ptr);}
>
> then you can fill a byte buffer with the three integer values:
>
> unsigned char bytes[sizeof(words)];
> unsigned char* ptr=bytes;
>
> for(i=0;i<sizeof(words)/sizeof(words[0]);i++){
> ptr=serialize_unsigned_int(ptr,words[i]);}
>
> write_buffer(bytes,ptr-bytes);
>
>
>
>
> Of course, if the protocol specifies that the integer values must be
> sent as text encoded in ASCII, you can just use sprintf:
>
> unsigned char bytes[128];
> int size=snprintf(bytes,sizeof(bytes),"0x%08x 0x%08x 0x%08x",2,0,1);
> write_byffer(bytes,size); /* or size+1 if the terminating null must be sent */
>
>
>
> --
> __Pascal Bourguignon__ http://www.informatimago.com/
> Our enemies are innovative and resourceful, and so are we. They never
> stop thinking about new ways to harm our country and our people, and
> neither do we. -- Georges W. Bush
|
|
|
|
|