How to read unsigned char from a socket - c

I have to receive a UDP packet from the socket. In this packet hour, min and sec are sent as UNSIGNED CHAR. When I receive it in a char[] and put in TextBox for displaying it is not displaying the actual data which are sent, but different values.
char buffer[10];
udpSocketRxCDP->readDatagram(buffer, sizeof(buffer));
ui->textEditsec->setText(buffer[2]);
Please suggest how I can get the actual data.

When you read from a socket, you are reading raw data. If you read it into a char[] buffer and use it as-is then the data is going to be interpreted as char. So either typecast the data to unsigned char when needed:
ui->textEditsec->setText( (unsigned char) buffer[2] );
Or define a suitable struct and typecast to that instead:
struct mypkt
{
unsigned char hour;
unsigned char minute;
unsigned char second;
...
};
ui->textEditsec->setText( ((mypkt*)buffer)->second );
Either way, assuming setText() actually expects a char* string as input, then use sprintf() or similar function to format a string:
char str[12];
sprintf(str, "%d", (int) ((mypkt*)buffer)->second);
ui->textEditsec->setText(str);

With the little given information, you might want to explicitly convert unsigned char to char.
Consider that some data may get corrupted. However, unless you really need it, you can send the data directly as signed char. We can't know whether it's a good choice or not though.

Related

Convert float data to Char data that has to be sent over UDP

I'm using C socket to send data to a Server, I found some example on internet but all of them show a char data sent over the network.
Instead, my data are float, so I need to convert these data from float to a char to send it, and on the Server side I must convert it back to float.
I read about sprintf or snprintf, but I found some problems with using these functions.
My situation:
packet[4] = {112.3, 113.4, 234.8, 599.4} "For example"
I need to send it as char to the Server.
Thanks in advance
If you're careful, you can use a union for representing your float as an array of chars:
typedef union packet
{
float f;
char c[4];
} packet;
Barring endianness (you might have to twiddle the float) and char being signed on some platforms and unsigned on others (adjust to taste), this is well-defined. In particular, the standard guarantees that
The address of f is the same as the zeroth element of c.
the c array is contiguous.
I think you are confused with char buffer and char value. The char buffer which is meant in UDP communication, is 8bit/1Byte minimum space required to carry data info. This is also equal to char which is also 8bit/1Byte in size. Hence people call it as char buffer. This dosenot mean they only can carry char value.
Typical float value is 4 bytes in length and this can be carried in 4byte char buffer. Please use memcpy operation and copy the contents of float variable in to 4Byte char array buffer. In the server, based on source IP, this value could be easily type casted to float value(using atof) from received char array buffer.
code snippet:
//At Tx - from client
float flt =xx.xx;
char charbuff[4] ={0};
memcpy(&charbuff,&flt,4);
//At Rx - in server
if(Rx done from specific IP which sends float value)
{
float rflt = (float)atof(buffer); //build in function available
}
int main(void)
{
float value= 22.3;
char valbuff[4]={0};
memcpy(&valbuff,&value,4);
float values = (float)atof(valbuff);
printf("Valore %f ",values);
}
When I run this code the out value is 0.0000, …
Since you just copied the float value to the char valbuff[4], the atof(valbuff) to put the value back into a float is quite out of place; you rather need
float values;
memcpy(&values, valbuff, sizeof values);

scanf("%s",input) doesnt work correctly

I am trying to interface my Nokia N95 with Proteus. It works almost fine, except of one thing. When I want to get the response from the modem, I use unsigned char input[20] and scanf("%s",input). When the modem receives a call, it send RING to the port, but what I get with scanf is RIG or RNG. What might be the problem?
#include <regx51.h>
#include <stdio.h>
#include <string.h>
sbit TE = P2^4;//for transmitting
unsigned char ch;
unsigned char ch2;
long i;
short bakar=0;
unsigned char Command_AT[]="AT\r";
unsigned char xdata Command_CPIN[]="AT+CPIN =\"0000\"\r";
unsigned char Command_CMGF[]="AT+CMGF=1\r";
unsigned char Command_CMGS[]="AT+CMGS =\"5555\"\r";
unsigned char msg_report[]="Ok";
unsigned char CtrlZ=0x1A;
unsigned char xdata Status_Ok[]="AT\rOK";
unsigned char Command_CHUP[]="AT+CHUP\r";
unsigned char input[10];
void iniSerial()
{
TMOD=0x20;
TH1=0XFD;
SCON=0x50;
TR1=1;
TI=1;
RI=0;
}
void delay()
{
for(i=1;i<=30000;i++); //Dont know how much exactly
}
void delay2()
{
for(i=1;i<=50000;i++);
}
void sendDeliveryReport()
{
puts(Command_AT);
delay();
puts(Command_CMGF);
delay();
puts(Command_CMGS);
delay();
puts(msg_report);
while(TI == 0);
SBUF = 0x1A;
}
void checkRing()
{
while(bakar!=1)
{
scanf("%s",&input);//problem is here
if(strcmp(input,"RING") == 0)
{
bakar=1;
delay();
puts(Command_CHUP);
}
delay2();
}
}
void main()
{
delay2(); //Wait for GSM modem to start.
TE=1; //Don't trasmit yet
iniSerial();
checkRing();
TE=0;
iniSerial();
sendDeliveryReport();
while(1); //Pause forever
}
Does that code really compile? The if-statement in void checkRing() has mismatched paranthesis.
ps. Sorry for the "answer" instead of a comment, but my reputation does not allow comments.
Your line
scanf("%s",&input);
is simply wrong. A good compiler should have told you if you have decent warning level.
&input is of type unsigned char (*)[10], that is a pointer to a unsigned char array. Use
scanf("%s",input);
instead. Here input decays to a unsigned char*, which is about what you want if what you expect is really a string and not arbitrary data. If your data may contain 0 bytes, you'd have to use read or something equivalent.
Edit: If your input is really a string use char instead of unsigned char.
I must say that this code seems to invite a hacker attack.
The line scanf("%s",&input); reads bytes until a newline, into the buffer on the stack. If more than 10 bytes are read, the buffer overflows and the stack is corrupted.
From there, the way to overwriting the return address and executing arbitrary code is short.
You must either use fgets, which allows you to limit the number of bytes read, followed by fscanf to stop at a delimiter, or use, as Daniel Fischer suggested, the format string "%9s" which won't store more than 10 bytes in the buffer (9 + terminating null).

Doubts in the strcpy function used

I am using two buffers which are of unsigned char and when I used the function strcpy, there is a compilation error which says "invalid conversion of unsigned char * to char *". Can anyone please tell me what difference does an unsigned buffer vs. signed buffer makes to the output? This is the program which I had tried.
main()
{
unsigned char buff[20] = "Michael";
unsigned char dst[20] = "Jackson";
strcpy(buff,dst);
printf("The string is %s\n",buff);
}
Now when i typecast the parametrs passed in strcpy to (char *),This programe works fine as shown below
main()
{
unsigned char buff[20] = "Michael";
unsigned char dst[20] = "Jackson";
strcpy((char *)buff,(char *)dst);
printf("The string is %s\n",buff);
}
2nd Question: Does typecasting to char* in the string function create any issues?
Please do let me know if you need any more inputs.
You can just change:
unsigned char buff[20] = "Michael";
unsigned char dst[20] = "Jackson";
to
char buff[20] = "Michael";
char dst[20] = "Jackson";
To think of it logically, A string cannot be signed or unsigned, it is not a numeric value to be treated that way, it is just an char array and you should declare and use it so.
Why do you get the error?
strcpy has the prototype:
char *strcpy(char *restrict s1, const char *restrict s2);
And what you are passing to it is, unsigned char*, when a function is called parameter type checking takes place and the compiler finds that you are not calling the function with proper type parameters and hence it complains about it, When you apply a cast the function arguments match and hence compilation passes.
Does typecasting to char in the string function create any issues?*
No, in this case it doesn't.
Though it makes more sense to change your usage of unsigned char for the reasons mentioned above in the answer.
Suggestion:
Strcpy is not safe, so you are much better off using strncpy, it allows you to explicitly specify how many characters to copy, rather than rely on null terminator of the source string, Also this helps avoiding buffer overflow since you explicitly specify a length.
The way you are using it should be fine.
But you shouldn't use unsigned char arrays with string handling functions. In C strings are char arrays, not unsigned char arrays. Since passing to strcpy discards the unsigned qualifier, the compiler warns.
As a general rule, don't make things unsigned when you don't have to.
strcpy wants char *'s, plain and simple. Cast your buffers to char *'s and you'll be fine. Then there's the whole safety problem with using strcpy in the first place...

ether_addr_octet in host order byte

I would like convert struct ether_addr (ether_addr_octet) to integer host byte order representation. Any ideas?
ntohl(eth->ether_addr_octet)
not working, because ether_addr_octet is a char array.
Regards
I'm not sure what the semantics of this are going to be.
The ether is 48bit, and the largest ntoh* is for 32bit values.
I suppose you can create a 64bit value parsing the char array, and calling ntohl() twice...
You can convert it to char and then you can do something else you want...
char *ether_ntoa_my(const struct ether_addr *addr){
static char buf[18];
sprintf(buf, "%02x%02x:%02x%02x:%02x%02x",
addr->ether_addr_octet[0], addr->ether_addr_octet[1],
addr->ether_addr_octet[2], addr->ether_addr_octet[3],
addr->ether_addr_octet[4], addr->ether_addr_octet[5]);
return buf;
}
I hope it helps

Copying between byte array and unsigned long

What's the best/recommended way to copy data between a byte array and an integer in C? Currently I'm using memcpy, which doesn't feel right to me. A sample of the sort of thing I'm doing is below.
struct alpha {
unsigned char byte_array[20];
}
void function(struct alpha *st) {
unsigned long num;
/* Do some stuff */
memcpy(st->byte_array, &num, sizeof(unsigned long));
/* Do more stuff */
memcpy(&num, st->byte_array, sizeof(unsigned long));
}
I assume I want to use casts somehow, but I'm not confident of how casting and pointer (de)referencing interacts, particularly when arrays get involved.
memcpy is the standard and portable tool for that effect. Modern optimized compilers will inline this call to something well adapted to your situation, e.g data types, allignement, size (if known at compile time), processor... So I think you should definitively stick to that and not mess around with some handmade optimizations.
It looks exactly the right way to me. Which is to say, when I had to do this, it was the way I did it.
Here's how to do it with casts:
/* Do some stuff */
*(unsigned long *)st = num;
/* Do more stuff */
num = *(unsigned long *)st;
You're casting your struct pointer to a pointer to an unsigned long, then dereferencing the pointer in the assignment statements.
It is not wrong, unless you know that "who" wrote the data into the array wrote them in an endianness different from the one used on your system. Say, e.g., if those data come from a "stream" sent by "someone" over the net. Then, if the protocol uses the so called "network byte order" (namely big endian), and your machine is not big endian, then you obtain wrong values.
Is there any particular reason you need to copy instead of just aliasing the two? e.g.:
union XXX {
char byte_array[20];
unsigned long num;
};
In theory, you don't get defined results when you write to one member of the union then read from the other member. In reality, there's essentially no possibility of getting anything different from what you're getting now -- except (of course) that you don't have to copy data to get from one view to the other -- you just use x.num to look at it as an unsigned long, and x.byte_array to look at it as an array of bytes.
memcpy is the safest way to do this sort of thing. If speed matters though, you can do some cast magic to let the compiler handle the copy natively for you:
*((unsigned long *)&st->byte_array[0]) = num;
num = *((unsigned long *)&st->byte_array[0]);
Both these will use built in register type copies instead of a function call of 4 bytes. If you want to read further into the byte_array, you must be careful of byte alignment issues with this though.
I prefer some default functions for this requirement,
for string to integer
int atoi ( const char * str );
and
for integer to string
char * itoa ( int value, char * str, int base );
#include <stdio.h>
#include <stdlib.h>
int main()
{
unsigned long int number;
unsigned char string[256];
printf ("Enter a number: ");
fgets ( string, 256, stdin );
number = atoi (string);
printf("number = %d\n",number);
//converting int to string
itoa (number,string,10); //10 is base here for decimal, 16 is used for Hex and 2 for Binary
printf ("string = %s\n",string);
return 0;
}
as per me atoi() function is fine. But in case you don't want to use itoa() or it is not available to you then you can just use sprintf()
sprintf (string,"%ld",number);
I hope it helps
Thanks
Alok.kr.

Resources