C Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me
Go Back   Dev Shed ForumsProgramming LanguagesC Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
Get inside! Sample the range of functionality easily built with JMSL Library for Time Series Data Analysis, Heat Maps, Portfolio Optimization, Monte Carlo Simulation, Stock Price Charting and more. Download Now!
  #1  
Old May 14th, 2003, 02:32 AM
phantom_turtle phantom_turtle is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: May 2003
Posts: 81 phantom_turtle User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 14 m 21 sec
Reputation Power: 6
UDP data convert from string to float or int?

I am currently working on a networking project and I am having trouble and I cant seam to find an answer.

First I send a udp packet from the client to the server:

Code:
sendto(sock,data,MAXDATASIZE,0,(struct sockaddr *)&server,sizeof(struct sockaddr));


Say that "data" is a variable containing a string.

Now the server recieves the udp packet:


Code:
recvfrom(sock, buf, MAXDATASIZE, 0, (struct sockaddr *) &remote_addr, &iRemoteAddrLen);


the variable "buf" holds the string recieved in the packet.

Now say buf = "0.1f,0.1f,0.2f" (A set of float coordinates in Opengl)

How can I take the string in "buf" and put the three seprate floats into three variables as floats. Like this:

Original string in "buf":

buf = "0.1f,0.1f,0.2f"

into,

Three seperate opengl floats:

x=0.1f
y=0.1f
z=0.2f

Make sense?

If any one has any ideas or suggestion on how to do this it would be a huge help.

Thanks

Reply With Quote
  #2  
Old May 14th, 2003, 10:08 AM
Scorpions4ever's Avatar
Scorpions4ever Scorpions4ever is offline
Banned ;)
Dev Shed God 5th Plane (7000 - 7499 posts)
 
Join Date: Nov 2001
Location: Glendale, Los Angeles County, California, USA
Posts: 7,442 Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level)Scorpions4ever User rank is Major General (70000 - 90000 Reputation Level) 
Time spent in forums: 1 Month 1 h 49 m 40 sec
Reputation Power: 797
Use sscanf() to separate the strings into 3 floats. In your case, the code would go something like this:
Code:
#include <stdio.h>
...
...
  char *foo="0.1f,0.2f,0.3f";
  float a, b, c;

  sscanf(foo, "%f%*c%*c%f%*c%*c%f", &a, &b, &c);
  printf("%f %f %f\n", a, b, c);

Hope this helps

Reply With Quote
  #3  
Old May 14th, 2003, 10:17 AM
dwise1_aol's Avatar
dwise1_aol dwise1_aol is offline
Contributing User
Dev Shed Expert (3500 - 3999 posts)
 
Join Date: Jan 2003
Location: USA
Posts: 3,803 dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level) 
Time spent in forums: 1 Month 11 h 55 m 53 sec
Reputation Power: 437
It's actually very easy to do. Just parse that string like you would if you had read it from a disk file or a user typing it in.

A lot of people here seem to like sscanf(). I never use it because in our C class nobody could get it to work right, so I've shied away from it ever since. I'll take a stab at it and let somebody else tell you what's wrong with it:
Code:
// DISREGARD
fields_converted = sscanf(buf,"%f,%f,%f",&x,&y,&z);
// DISREGARD

EDIT:
Please disregard my attempt at sscanf. I ran a test program and it only converts the first field. Scorpion's example does work. If you are not familiar with sscanf, then you might want to ask him how his format string works. I'm going through the scanf man page now to figure it out for myself.

EDIT2:
My sscanf problem was due to the trailing f's. This one does work:
Code:
fields_converted = sscanf(buf,"%ff,%ff,%ff",&x,&y,&z);

Like I've said here before, I'm learning a lot on this forum.


In our embedded project here at work, we use strtok a lot. Here's how I would do it:
Code:
#include <stdlib.h>  // for definition of NULL and for atof()
#include <string.h> // for strtok

char *sp;

sp = strtok(buf,",");
if (sp != NULL)
{
    x = atof(sp);
    sp = strtok(NULL,",");
    if (sp != NULL)
    {
        y = atof(sp);
        sp = strtok(NULL,",");
        if (sp != NULL)
            z = atof(sp);
    }
}


BTW, I recently learned that if you send binary data, then you are subject to differences in byte order. Plus, if you send a struct across as a block of binary data, then you are subject to system differences in byte alignment and padding. Therefore, if you are going to send binary data, you must define an exact format for the data, including number of bytes per field and the byte order (should be network order anyway). Then you will need to explicitly put each field of your struct into the packet and explicit read it out on the other end.

Of course, your use of a character string is one way to get around this problem.

Last edited by dwise1_aol : May 14th, 2003 at 10:47 AM.

Reply With Quote
  #4  
Old May 14th, 2003, 07:29 PM
phantom_turtle phantom_turtle is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: May 2003
Posts: 81 phantom_turtle User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 14 m 21 sec
Reputation Power: 6
Thanks Scorpions4ever that code did the trick. I even ran it thru some OpenGL code to check it liked the floats.


Quote:
BTW, I recently learned that if you send binary data, then you are subject to differences in byte order. Plus, if you send a struct across as a block of binary data, then you are subject to system differences in byte alignment and padding. Therefore, if you are going to send binary data, you must define an exact format for the data, including number of bytes per field and the byte order (should be network order anyway). Then you will need to explicitly put each field of your struct into the packet and explicit read it out on the other end.



Quote:
Of course, your use of a character string is one way to get around this problem.


lol...I didnt realize that there was another way to do it. That was one thing I wasn't able to grasp from the online tutorials on winsock(cant afford the book). How does the recieving socket know what the packet is? like a string or a float? I mean I use this function to send


Code:
sendto(sock,data,MAXDATASIZE,0,(struct sockaddr *)&server,sizeof(struct sockaddr));


Can I say

Code:
float data[3] = {0.1f,0.2f,0.3f}


and then send data as an array and the other side treat it as an array? I thought you had to send stuff as strings....

Reply With Quote
  #5  
Old May 14th, 2003, 09:36 PM
infamous41md's Avatar
infamous41md infamous41md is offline
not a fan of fascism (n00b)
Dev Shed Frequenter (2500 - 2999 posts)
 
Join Date: Feb 2003
Location: ct
Posts: 2,756 infamous41md User rank is Sergeant (500 - 2000 Reputation Level)infamous41md User rank is Sergeant (500 - 2000 Reputation Level)infamous41md User rank is Sergeant (500 - 2000 Reputation Level)infamous41md User rank is Sergeant (500 - 2000 Reputation Level)infamous41md User rank is Sergeant (500 - 2000 Reputation Level) 
Time spent in forums: 2 Days 11 h 4 m 29 sec
Reputation Power: 26
nope you dont have to send strings, u just have to cast whatever you send. you could do:

struct data{
int x
char y
DWORD m
float h} message

sendto(sock,(char *)message,sizeof(message),0,(struct sockaddr *)&server,sizeof(struct sockaddr));

Reply With Quote
  #6  
Old May 15th, 2003, 12:11 AM
dwise1_aol's Avatar
dwise1_aol dwise1_aol is offline
Contributing User
Dev Shed Expert (3500 - 3999 posts)
 
Join Date: Jan 2003
Location: USA
Posts: 3,803 dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level)dwise1_aol User rank is Lieutenant Colonel (40000 - 50000 Reputation Level) 
Time spent in forums: 1 Month 11 h 55 m 53 sec
Reputation Power: 437
Quote:
Originally posted by infamous41md
nope you dont have to send strings, u just have to cast whatever you send. you could do:

struct data{
int x
char y
DWORD m
float h} message

sendto(sock,(char *)message,sizeof(message),0,(struct sockaddr *)&server,sizeof(struct sockaddr));


Not quite. That would only work if both ends of the connection are the exact same architecture. If both ends are different architecture (<sarcasm>whenever would that happen on the Internet?</sarcasm>), then three things will very likely bite you hard:
1. Byte order (what Jon Snader calls "byte sex"). Host order could very well not be the same as network order. That's why you need to set the address struct's port with htons(). You will need to do the same for the binary data. The terms "big-endian" and "little-endian" describe the two possible byte orders.
2. sizeof(int). The size of the int type is implementation dependent. That means it could be 16 bits or 32 bits or even 64 bits.
3. Byte alignment. an int will normally be aligned with the data bus, which could be 16, 32, or 64 bits wide. This will affect the alignment of the fields within the struct, such that there could very well be extra bytes of padding between fields. Therefore, the "same" struct on different architectures could be different sizes and fields therein could get misread.

Case in point of #3: For our first Linux file manipulation program, I started working on it on a Windows 98SE machine, then copied the files over to a Linux box to finish it. That included a data file of structs which I just could not get to work right. Upon examination, I found that the filesize was wrong. I deleted it and recreated it under Linux. This time it worked and the filesize was correct.

That is why I wrote:
Quote:
Therefore, if you are going to send binary data, you must define an exact format for the data, including number of bytes per field and the byte order (should be network order anyway). Then you will need to explicitly put each field of your struct into the packet and explicit read it out on the other end.


You should find examples of such format definitions in the NTP (Network time Protocol -- RFC 1769) RFCs and others.

Last edited by dwise1_aol : May 15th, 2003 at 03:14 PM.

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming LanguagesC Programming > UDP data convert from string to float or int?


Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump


Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 





© 2003-2008 by Developer Shed. All rights reserved. DS Cluster 6 hosted by Hostway