因为智能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));
}
}