0

I am in bit of a problematic situation here:

I have a simple C server (can't use Qt TcpServer, limitations of the embedded board) which sends double data (generated by GPIO ports) over tcpsocket using send(). If I have a simple C client (in my Linux PC) then I am able to get the real time data as is generated with the help of recv(). Here is my server code:

int main (void){
    int s,b,l,fd,sa,bytes,on=1;
    char buf[BUF_SIZE],fname[255];
    struct sockaddr_in channel;

    long long sum=0;
    double average=0;
    int i,j;
    int srno=0;

    s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(s<0)
    {
        printf("socket creation failure");
        exit(0);
    }
    setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&on,sizeof(on));
    memset(&channel,0,sizeof(channel));
    channel.sin_family=AF_INET;
    channel.sin_addr.s_addr=htonl(INADDR_ANY);
    channel.sin_port=htons(SERVER_PORT);
    b=bind(s, (struct sockaddr *)&channel,sizeof(channel));
    if(b<0)
    {
        printf("bind error");
        exit(0);
    }
    listen(s,5);
    while(1)
    {
        printf("waiting for request\n");
        sa=accept(s,0,0);
        if(sa<0)
        {
            printf("accept failure");
        }
        for (i=1; i<=56; i++)               //for 10 sec >> 56
        {   
            for(j=1;j<=20;j++)
            {

            //more than 100 lines of code here
            }               
            average=(sum/20)*1.22;
            send(sa, &average, sizeof(average), 0);

            //int tmp = htonl((uint32_t)average); //tried this also
            //send(sa, &tmp, sizeof(tmp), 0);

            // int n = write(sa, &average, sizeof(average)) //and tried this also
            // if(n<0){
            // printf("error");}

            printf("%lld \n", average);
            srno++; 
            sum=0;
            average=0;      
        }
    }
    remove_gpio();  
    close(s);
    return 0;
}

But I am unable to get to display the data in Qt Client, it is driving me crazy. In my QtextEdit I get non-ASCII characters, whatever I try. inside my startRead() I did

...

QByteArray Data = socket->readAll();

ui->textEdit->append(QString(Data));

...

I also tried using other methods bytesavailable() canreadLine(), and also went through other links but was unsuccessful.

Non-ASCII crazy characters is what I get everytime. Sorry not able to give a pic due to low rep. I need help regarding sending double data through socket and be able to work with the data or atleast display them in a QTextEdit/QPlainTextEdit.

Thanks.

rNov
  • 61
  • 1
  • 15
  • 1
    The code misses to closing braces `}`. And is not formatted too nicely. – alk Dec 09 '13 at 12:17
  • Sorry, I missed a few braces while copying it. But the server code does work. I cannot seem to get the double data on the Client side through sockets though. – rNov Dec 09 '13 at 12:26
  • 1
    no need to add "solved" to the title, the icon with upvotes changes when you accept an answer – ratchet freak Dec 09 '13 at 12:49
  • The braces you added seem to be misplaced, at least one off them! – alk Dec 09 '13 at 12:55

4 Answers4

3

as ciphor said you are trying to display binary directly as text

you'll want to use a datastream to convert

QByteArray Data = socket->readAll();
QDataStream dstream (Data);
double d;
while(!dstream.atEnd())
{
    dstream >> d;
    ui->textEdit->append(QString::number(d));
}
ratchet freak
  • 47,288
  • 5
  • 68
  • 106
3

You need to actually design, specify, and implement a protocol. Otherwise, it's as if your client is speaking Chinese and your server listening for Spanish. Because TCP is a byte-stream protocol, you need to precisely specify how the two programs will interchange data as a stream of bytes. Then design both sides to send a stream of bytes in accord with the specification and receive a stream of bytes in accord with the specification. To help you get started, you should thoroughly study the specifications for existing protocols layered on top of TCP such as IRC, NNTP, SMTP, IMAP, and so on.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
1

The conversion specifier for double is "lf".

The "lld" the code is using is for long long integer.

So use:

printf("%lf\n", average);
alk
  • 69,737
  • 10
  • 105
  • 255
  • yea that seems to display the data on XTerminal but I still don't get the data on the QTextEdit via sockets. – rNov Dec 09 '13 at 12:24
  • 1
    See the answers to this qurstion on how to convert a double to string: http://stackoverflow.com/q/332111/694576 – alk Dec 09 '13 at 12:29
0

You are sending the data in format of double precision binary, but trying to display as a string in your client, that is the reason of non-ASCII.

If you want to send ASCII, you should convert the data into string format before sending it at server side.

char buf[20] = {0};
average=(sum/20)*1.22;
sprintf(buf, "%lld", average);
send(sa, &buf[0], strlen(buf), 0);
ciphor
  • 8,018
  • 11
  • 53
  • 70
  • Can you point me in the right direction with a few lines of code? Nothing seems to work. I tried htons() too. – rNov Dec 09 '13 at 12:21
  • 1
    Transferring binary data is perfectly alright as long endianness is not an issue and sender and receiver are aware what kind of data is sent. Here the `double` should be ok. – alk Dec 09 '13 at 12:23
  • How do I convert the double data to string and write to the sockets? – rNov Dec 09 '13 at 12:29
  • Printing a double using `"lld"` is **not** nice! – alk Dec 09 '13 at 12:54