TCP套接字网络通信

来源:互联网 发布:淘宝api php实例 编辑:程序博客网 时间:2024/06/05 03:54

因为智能LED控制系统的项目中要用到C/S模式的网络通信,且客户端是基于qtopia2.2.0的应用程序,而服务器端Linux C程序。所以,我在编写QT应用程序时没有用到QTcpSocket类和QTcpServer类,所有的功能都是基于Linux C实现的。

在编译的时候出现了几个问题:

1.        

[root@zzc network]# make

g++ -c -pipe -DQWS -fno-exceptions -fno-rtti -Wall -W-O2 -DNO_DEBUG -I/opt/EmbedSky/Qte/x86-qtopia-2.2.0/qt2/include-I/opt/EmbedSky/Qte/x86-qtopia-2.2.0/qtopia/include -o Network.o Network.cpp

Network.cpp: In constructor‘Network::Network(QWidget*, const char*, uint)’:

Network.cpp:54: 错误:对‘Network::connect(QPushButton*&,const char [11], Network* const, const char [8])’的调用没有匹配的函数

Network.h:36: 附注:备选为: virtual voidNetwork::connect()

Network.cpp:55: 错误:对‘Network::connect(QPushButton*&,const char [11], Network* const, const char [11])’的调用没有匹配的函数

Network.h:36: 附注:备选为: virtual void Network::connect()

Network.cpp:56: 错误:对‘Network::connect(QPushButton*&,const char [11], Network* const, const char [9])’的调用没有匹配的函数

Network.h:36: 附注:备选为: virtual voidNetwork::connect()

make: *** [Network.o] 错误 1

原因:有自定义的槽函数与connect()函数重名。Connect按钮对应的槽函数和槽函数与信号的连接函数都是connect,重名了。(此时还没有加入连接服务器的函数connect)

 

2.        

g++ -c -pipe -DQWS -fno-exceptions -fno-rtti -Wall -W-O2 -DNO_DEBUG -I/opt/EmbedSky/Qte/x86-qtopia-2.2.0/qt2/include-I/opt/EmbedSky/Qte/x86-qtopia-2.2.0/qtopia/include -o Network.o Network.cpp

In file included from Network.cpp:9:

Network.h:36: 错误:‘virtual voidNetwork::connet()’的声明

Network.h:30: 错误:与先前的声明‘QPushButton* Network::connet’冲突

Network.cpp: In constructor‘Network::Network(QWidget*, const char*, uint)’:

Network.cpp:34: 错误:invalid use of member (didyou forget the ‘&’ ?)

Network.cpp:35: 错误:invalid use of member (didyou forget the ‘&’ ?)

Network.cpp:35: 错误:‘->’的左操作数不是一个指针

Network.cpp:36: 错误:invalid use of member (didyou forget the ‘&’ ?)

Network.cpp:36: 错误:‘->’的左操作数不是一个指针

Network.cpp:56: 错误:对‘Network::connect(<unresolvedoverloaded function type>, const char [11], Network* const, const char [10])’的调用没有匹配的函数

/opt/EmbedSky/Qte/x86-qtopia-2.2.0/qt2/include/qobject.h:110:附注:备选为: static boolQObject::connect(const QObject*, const char*, const QObject*, const char*)

/opt/EmbedSky/Qte/x86-qtopia-2.2.0/qt2/include/qobject.h:209:附注:         bool QObject::connect(const QObject*,const char*, const char*) const

make: *** [Network.o] 错误 1

原因:自定义的槽函数的函数名与按键对象重名。我在界面中有一个按钮的名字设成了connect,而信号与槽的连接函数名也是connect。

 

3.       加上套接字的连接函数connect之后,又出现了函数重名的错误。

解决方法:套接字的连接中的connect写成: ::connect,即表示此时的connect函数是系统提供的函数,与信号与槽的连接函数区分开来。

 

4.        

Network.cpp:116: 错误:不能将‘int connect(int, constsockaddr*, socklen_t)’的实参‘2’从‘sockaddr_in*’转换到‘const sockaddr*’

make: *** [Network.o] 错误 1

解决:注意:connect的声明,第2个参数是sockaddr*,不是sockaddr_in*,因为addr是定义的sockaddr_in类型的,所以要强制转化成struct sockaddr类型。

函数要写成: ::connect(s,(struct sockaddr*)&addr,sizeof(addr))

struct sockaddr与sockaddr_in的区别如下:

struct sockaddr

{

       unsigned  short sa_family;     /* address family,AF_xxx */

       char  sa_data[14];                 /* 14 bytes of protocoladdress */

};

 

sockaddr_in(在netinet/in.h中定义):

struct sockaddr_in

{

       short  int sin_family;                     /* Address family */

       unsigned  short int  sin_port;       /* Port number */

       struct  in_addr sin_addr;              /* Internetaddress */

       unsigned  char sin_zero[8];         /* Same sizeas struct sockaddr */

};

struct  in_addr

{

       unsigned  long s_addr;

};

在实验中发现,char*类型可强制转化成QString类型 ,如

char *buffer;

QString(buffer);即可。

最后,贴上修改过后调试成功的连接和发送槽函数的实现:

void Network::conect(){    //qWarning( "Network::conect(): Not implemented yet!" );   struct sockaddr_in addr ;   char mybuffer[256];   if( (s=socket(AF_INET,SOCK_STREAM,0))<0 )   {      perror("socket");      ::exit(1);   }   else   {    printf("socket created .\n");    printf("socked id: %d \n",s);}   bzero(&addr,sizeof(addr));   addr.sin_family =AF_INET;   addr.sin_port=htons(PORT);   addr.sin_addr.s_addr=inet_addr(REMOTE_IP);   if(::connect(s,(struct sockaddr*)&addr,sizeof(addr))<0)   {      perror("connect");      ::exit(1);   }   else   {      printf("connected ok!\n");      printf("remote ip:%s\n",REMOTE_IP);      printf("remote port:%d\n",PORT);    }   recv(s ,mybuffer,sizeof(mybuffer),0);   printf("%s\n",mybuffer);}void Network::send(){    //qWarning( "Network::send(): Not implemented yet!" );   char mybuffer[256];   QString message = sendEdit->text();  //获取要发送的内容   printf("%d\n",message.length());//打印发送内容的长度   if(::send(s,message,message.length(),0)<0)      {         perror("send");         exit(1);      }      else      {         bzero(mybuffer,sizeof(mybuffer));         recv(s ,mybuffer,sizeof(mybuffer),0);         textReceive->setText( QString(mybuffer));      }   }

0 0