How to link socket programming in c and Qt gui
-
wrote on 8 Feb 2013, 08:36 last edited by
Hi everyone, I wrote client/server socket programming in c language to send image over. And my program can receive image and save it somewhere else. But now I wanna appear image as soon as I receive. I think I need to use gui. So I use Qt gui. But I don't know how to link with my gui and my socket programming. If anyone knows, pls kindly show me a way to do it. Thanks a lot.
Client.c
@
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>
#include <stdio.h>int fileSEND(char *server, int PORT, char *lfile, char *rfile)
{
int socketDESC;
struct sockaddr_in serverADDRESS;
struct hostent *hostINFO;
FILE *file_to_send;
int ch;
char toSEND[1];
char remoteFILE[4096];
int count1=1, count2=1, percent;hostINFO = gethostbyname(server);
if(hostINFO==NULL)
{
printf("Problem interpreting host\n");
return 1;
}socketDESC = socket(AF_INET, SOCK_STREAM, 0);
if(socketDESC<0)
{
printf("Cannot create socket\n");
return 1;
}serverADDRESS.sin_family = hostINFO->h_addrtype;
memcpy((char *) &serverADDRESS.sin_addr.s_addr, hostINFO->h_addr_list[0],hostINFO->h_length);
serverADDRESS.sin_port = htons(PORT);if(connect(socketDESC,(struct sockaddr *)&serverADDRESS,sizeof(serverADDRESS))<0)
{
printf("Cannot connect\n");
return 1;
}file_to_send = fopen(lfile, "r");
if(!file_to_send)
{
printf("Error opening file\n");
close(socketDESC);
return 0;
}
else
{
long fileSIZE;
fseek(file_to_send,0,SEEK_END);
fileSIZE=ftell(file_to_send);
rewind(file_to_send);sprintf(remoteFILE,"FBEGIN:%s:%ld\r\n",rfile,fileSIZE);
send(socketDESC,remoteFILE,sizeof(remoteFILE),0);
percent = fileSIZE/100;
while((ch=getc(file_to_send))!=EOF)
{
toSEND[0]=ch;
send(socketDESC,toSEND,1,0);
if(count1==count2)
{
printf("33[0;0H");
printf("\33[2J");
printf("Filename: %s\n",lfile);
printf("Filesize: %ld Kb\n", fileSIZE/1024);
printf("Percent: %d%% (%d Kb)\n", count1/percent,count1/1024);
count1+=percent;
}
count2++;
}
}
fclose(file_to_send);
close(socketDESC);
return 0;
}int main()
{
fileSEND("localhost", 4547, "1.jpeg", "received.jpeg");
return 0;
}@
server.c
@
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>
#include <stdio.h>#define PORT 4547
int parseARGS(char **args, char *line)
{
int tmp = 0;
args[tmp] = strtok(line, ":" );
while ((args[++tmp] = strtok(NULL, ":" )) != NULL);
return tmp -1;
}int main()
{
char *header[4096];
int listenSOCKET, connectSOCKET;
socklen_t clientADDRESSLENGTH;
struct sockaddr_in clientADDRESS, serverADDRESS;
char recvBUFF[4096];
char *filename, *filesize;
FILE *recvFILE;
int received = 0;
char tempstr[4096];int count1=1, count2=1, percent;
listenSOCKET = socket(AF_INET, SOCK_STREAM, 0);
if (listenSOCKET <0)
{
printf("Cannot create socket\n");
close(listenSOCKET);
return 1;
}serverADDRESS.sin_family = AF_INET;
serverADDRESS.sin_addr.s_addr = htonl(INADDR_ANY);
serverADDRESS.sin_port = htons(PORT);if (bind(listenSOCKET, (struct sockaddr *)&serverADDRESS, sizeof(serverADDRESS))<0)
{
printf("Cannot bind socket\n");
close(listenSOCKET);
return 1;
}listen(listenSOCKET, 5);
clientADDRESSLENGTH = sizeof(clientADDRESS);
connectSOCKET = accept(listenSOCKET,(struct sockaddr *)&clientADDRESS, &clientADDRESSLENGTH);
if (connectSOCKET<0)
{
printf("Cannot accpet connection\n");
close(listenSOCKET);
return 1;
}while(1)
{
if(recv(connectSOCKET, recvBUFF, sizeof(recvBUFF),0))
{
if(!strncmp(recvBUFF,"FBEGIN",6))
{
recvBUFF[strlen(recvBUFF)-2] = 0;
parseARGS(header, recvBUFF);
filename = header[1];
filesize = header[2];
}
recvBUFF[0] = 0;
recvFILE = fopen(filename, "w");
percent = atoi(filesize)/100;
printf("Current percent value: %d\n",percent);
while(1)
{
if(recv(connectSOCKET,recvBUFF,1,0) != 0)
{
fwrite(recvBUFF,sizeof(recvBUFF[0]),1,recvFILE);
if(count1==count2)
{
printf("33[0;0H");
printf("\33[2J");
printf("Filename: %s\n", filename);
printf("Filesize: %d Kb\n", atoi(filesize)/1024);
printf("Percent: %d%% (%d Kb)\n", count1/percent,count1/1024);
count1+=percent;
printf("Show count1 value: %d\n",count1);
}
count2++;
printf("Show count2 value: %d\n", count2);
received++;
recvBUFF[0] = 0;
}
else
{
close(listenSOCKET);
return 0;
}
}
close(listenSOCKET);
}
else
{
printf("Client dropped connection\n");
}
return 0;
}
}@
my qt image gui
@
#include <QtGui/QApplication>
#include "mainwindow.h"
#include <QLabel>int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QImage myImage;myImage.load("/home/sanda199/programs/received.jpeg"); QLabel myLabel; myLabel.setPixmap(QPixmap::fromImage(myImage)); myLabel.show(); return a.exec();
}
@ -
wrote on 8 Feb 2013, 09:13 last edited by
It is not so much code, why don't you use Qt's sockets? This will give you flexible communication possibilities between background tasks and GUI... And this will be even less code to write... And of cause more comfortable to maintain.
-
wrote on 8 Feb 2013, 09:19 last edited by
I was forced to use socket programming in c language. And I am not familiar with Qt so much. So is it not possible to do what I want?
[quote author="AcerExtensa" date="1360314792"]It is not so much code, why don't you use Qt's sockets? This will give you flexible communication possibilities between background tasks and GUI... And this will be even less code to write... And of cause more comfortable to maintain. [/quote] -
wrote on 8 Feb 2013, 09:42 last edited by
First of all, I would prefer to use OpenCV or SDL instead of Qt to display the image.
It's not so huge like Qt and it is a C library and not a C++ library.If you want to do that in Qt, I prefere to put the while(1)-loop in a QThread and emit a signal, if a full image was received (every JPG Image end with FF D9 and start with FF D8). You can load the image data through QImage::loadFromData
-
wrote on 8 Feb 2013, 10:18 last edited by
QThread is the required class, use a thread to receive/send from/to socket and use a gui on front to display it. You need no to worry about halting a gui as multitasking takes place in this scenario.
-
wrote on 8 Feb 2013, 10:23 last edited by
There are multiple options, but because your C code isn't a QObject, you will not be able to utilize the signal/slot methode. For the code to be compiled in Qt please insert in your c-header files:
@#ifdef __cplusplus
extern "C"
{
#endif
.... Function declarations here for C function
#ifdef __cplusplus
}
#endif@That will make your C-code compilable in Qt. The C functions can be called in the MainWindow class without problems. Calling C++ functions from your C code is a bit more tricky! So I would suggest to have a Getter/Setter function in your C code that holds the state you need to know in you Gui. In your Gui set a e.g. 50 msec timer that will read out the getter, if needed do something with the GUI, like display a picture just received.
Hope this helps,
Greetz
3/6