基于QT的TCP socket通信编程论文.docx
《基于QT的TCP socket通信编程论文.docx》由会员分享,可在线阅读,更多相关《基于QT的TCP socket通信编程论文.docx(14页珍藏版)》请在冰豆网上搜索。
基于QT的TCPsocket通信编程论文
嵌入式系统应用
大作业设计文档
题目:
基于QT的TCPsocket通信程序
课程名:
嵌入式系统应用
院系:
专业班级:
通信工程
学号:
学生姓名:
2009年12月24日
目录
1、QT简介3
2、需求分析4
2.1功能:
4
2.2设计要求:
4
3、概要设计4
4、详细设计5
4.1TCPsocket通信工作原理5
4.2猜字游戏的功能说明6
4.3猜字游戏的实现6
4.4猜字游戏服务器端的交叉编译10
5、调试分析12
6、测试结果13
7、参考文献13
1、QT简介
Qt是诺基亚开发的一个跨平台的C++图形用户界面应用程序框架。
它提供给应用程序开发者建立艺术级的图形用户界面所需的所用功能。
Qt是完全面向对象的,很容易扩展,并且允许真正地组件编程。
Qt是一个跨平台的C++图形用户界面应用程序框架。
它提供给应用程序开发者建立艺术级的图形用户界面所需的所用功能。
Qt是完全面向对象的,很容易扩展,并且允许真正地组件编程。
自从1996年早些时候,Qt进入商业领域,它已经成为全世界范围内数千种成功的应用程序的基础。
Qt也是流行的Linux桌面环境KDE的基础,KDE是所有主要的Linux发行版的一个标准组件。
Qt支持下述平台:
MS/Windows-95、98、NT4.0、ME、2000、XP和Vista
Unix/X11-Linux、SunSolaris、HP-UX、CompaqTru64UNIX、IBMAIX、SGIIRIX和其它很多X11平台
Macintosh-MacOSX
Embedded-有帧缓冲(framebuffer)支持的Linux平台,WindowsCE。
Qt是诺基亚公司的一个产品。
Qt的良好封装机制使得Qt的模块化程度非常高,可重用性较好,对于用户开发来说是非常方便的。
Qt提供了一种称为signals/slots的安全类型来替代callback,这使得各个元件之间的协同工作变得十分简单。
3.丰富的API
Qt包括多达250个以上的C++类,还提供基于模板的collections,serialization,file,I/Odevice,directorymanagement,date/time类。
甚至还包括正则表达式的处理功能。
Qt被按不同的版本发行:
Q商业版提供给商业软件开发。
它们提供传统商业软件发行版并且提供免费升级和技术支持服务。
如果要获得最新信息,请浏览诺基亚公司QtSoftware网站页面,或者与sales@联系。
商业版多一些扩展模块。
Qt开源版是Qt仅仅为了开发自由和开放源码软件提供的Unix/X11版本。
在Q公共许可证和GNU通用公共许可证下,它是免费的。
最新的版本可以在这里下载。
从计划于2009年3月发布的Qt4.5起,诺基亚将为Qt增添新的开源LGPL授权选择。
Qt/嵌入式开源版是Qt为了开发自由软件提供的嵌入式版本。
在GNU通用公共许可证下,它是免费的。
Qt文件格式
Apple公司开发的一种音频、视频文件格式,用于保存音频和视频信息,具有先进的音频和视频功能,由包括AppleMacOS,MicrosoftWindows95/98/NT在内的所有主流计算机操作系统支持。
是MAC常用播放软件——Quicktime的主要视频格式之一(其他的还有MOV等),Qt文件格式支持25位彩色,支持RLC、JPEG等领先的集成压缩技术,提供150多种视频效果。
2、需求分析
2.1功能:
该设计主要实现基于TCP的socket编程的猜字游戏,分服务器和客户端,服务端监听客户端的连接,当客户端连接上服务器时,通过给服务器发送数字来与服务器实现通信。
当客户端发送一个数字给服务器时,服务器进行处理。
2.2设计要求:
程序设计对于客户端的输入值有严格的要求,输入形式为数字,输入值的范围取在0到9之间,当输入值超出这个范围时,提示出错,并不给予处理。
根据客户端的输入,程序判断输入值,然后给予:
正确、出错、请输入的处理。
服务器从网络读取输入数据,并与事先随机生成的数字比较,相等则提示正确,反之,则提示错误,并把正确的数字发送到客户端显示出来。
3、概要设计
【1】TCP客户端的工作流程:
(1)创建TCP套接口。
客户端也是通过调用socket()函数来创建套接口。
(2)指定服务器IP地址和端口
(3)建立与服务器的链接。
通过调用connect()函数与服务器取得链接。
connect函数原型为:
#include
#include
intconnect(intsockfd,conststructsockadd*servaddr,socklen_t*addrlen);
(4)读入并输出服务器的应答
(5)终止程序
【2】TCP服务器的工作流程:
(1)创建TCP套接口。
客户端也是通过调用socket()函数来创建套接口。
(2)通过bind函数把socket的与主机的信息进行绑定。
(3)通过listen的函数监听客户端的连接。
(3)通过accept接受客户端的连接。
(4)读入并输出服务器的应答。
(5)终止程序。
服务器与客户端建立连接后,服务器创建一个ClientSocket来处理请求,
4、详细设计
4.1TCPsocket通信工作原理
客户端:
(1)创建TCP套接口。
客户端也是通过调用socket()函数来创建套接口。
(2)指定服务器IP地址和端口
(3)建立与服务器的链接。
通过调用connect()函数与服务器取得链接。
(4)读入并输出服务器的应答
(5)终止程序
服务器:
(1)创建TCP套接口。
客户端也是通过调用socket()函数来创建套接口。
(2)通过bind函数把socket的与主机的信息进行绑定。
(3)通过listen的函数监听客户端的连接。
(3)通过accept接受客户端的连接。
(4)读入并输出服务器的应答。
(5)终止程序。
4.2猜字游戏的功能说明
实现以下功能:
(1)客户端程序从标准输入,从键盘读入一个数字并发送给服务器。
(2)服务器从网络输入,读取该数并把它与事先随机生成的数字相比较,若相等,则提示用户猜对了;否则,提示错误并把正确数字发送给客户显示出来。
4.3猜字游戏的实现
(1)TCP客户端实现Client:
connect(send,SIGNAL(clicked()),SLOT(sendToServer()));
connect(close,SIGNAL(clicked()),SLOT(closeConnection()));
connect(quit,SIGNAL(clicked()),qApp,SLOT(quit()));
connect(Connect,SIGNAL(clicked()),SLOT(connectToServer()));
//createthesocketandconnectvariousofitssignals
socket=newQSocket(this);
connect(socket,SIGNAL(connected()),SLOT(socketConnected()));
connect(socket,SIGNAL(connectionClosed()),SLOT(socketConnectionClosed()));
connect(socket,SIGNAL(readyRead()),SLOT(socketReadyRead()));
connect(socket,SIGNAL(error(int)),SLOT(socketError(int)));
QVBoxLayout*l=newQVBoxLayout(this);
l->addWidget(infoText,10);
l->addWidget(hb,1);
l->addWidget(addrBox,1);
l->addWidget(buttonBox,1);
//l->addWidget(Connect,1);
//l->addWidget(close,1);
//l->addWidget(quit,1);
//connecttotheserver
infoText->append(tr("Tyingtoconnecttotheserver"));
//socket->connectToHost(host,port);
}
voidQClient:
:
closeConnection()
{
socket->close();
if(QSocket:
:
Closing==socket->state()){
connect(socket,SIGNAL(delayedCloseFinished()),SLOT(socketClosed()));
}
else{
socketClosed();
}
}
voidQClient:
:
sendToServer()
{
//writetotheserver
if(QSocket:
:
Connected==socket->state()){
QTextStreamos(socket);
os<text()<<"\n";
inputText->setText("");
}
else{
//Thesocketisunconnected
infoText->append(tr("Theserverislost\n"));
}
}
voidQClient:
:
connectToServer()
{
socket->connectToHost(addrText->text(),8034);
}
voidQClient:
:
socketReadyRead()
{
//readfromtheserver
while(socket->canReadLine()){
infoText->append(socket->readLine());
}
}
voidQClient:
:
socketConnected()
{
infoText->append(tr("Connectedtoserver\n"));
}
voidQClient:
:
socketConnectionClosed()
{
infoText->append(tr("Connectionclosedbytheserver\n"));
}
voidQClient:
:
socketClosed()
{
infoText->append(tr("Connectionclosed\n"));
}
voidQClient:
:
socketError(inte)
{
if(e==QSocket:
:
ErrConnectionRefused){
infoText->append(tr("ConnectionRefused\n"));
}
elseif(e==QSocket:
:
ErrHostNotFound){
infoText->append(tr("HostNotFound\n"));
}
elseif(e==QSocket:
:
ErrSocketRead){
infoText->append(tr("SocketReadError\n"));
}
}
(2)TCP服务器实现Server:
classClientSocket:
publicQSocket
{
Q_OBJECT
public:
ClientSocket(intsock,QObject*parent=0,constchar*name=0):
QSocket(parent,name)
{
line=0;
connect(this,SIGNAL(readyRead()),SLOT(readClient()));
connect(this,SIGNAL(connectionClosed()),SLOT(connectionClosed()));
setSocket(sock);
}
~ClientSocket()
{
}
privateslots:
voidreadClient()
{
while(canReadLine()){
QTextStreamos(this);
randomNUM=random()%10;
clientNumber=atoi(readLine());
if(clientNumber<0||clientNumber>9)
os<"<<"Pleaseinputanumber.";
else{
if(clientNumber==randomNUM)
os<"<<"Good,youareright.\n";
else
os<"<<"sorry,therightnumberis"<<""<}
line++;
}
}
voidconnectionClosed()
{
deletethis;
}
};
classSimpleServer:
publicQServerSocket
{
Q_OBJECT
public:
SimpleServer(QObject*parent=0):
QServerSocket(8034,1,parent)
{
if(!
ok()){
qWarning("Failedtobindtoport5000");
exit
(1);
}
}
~SimpleServer()
{
}
voidnewConnection(intsocket)
{
(void)newClientSocket(socket,this);
emitnewConnect();
}
(3)signals:
voidnewConnect();
};
classServerInfo:
publicQVBox
{
Q_OBJECT
public:
ServerInfo()
{
SimpleServer*server=newSimpleServer(this);
QStringitext=QString(
"shixiaoyu\n"
"120071102139."
);
QLabel*lb=newQLabel(itext,this);
lb->setAlignment(AlignHCenter);
infoText=newQTextView(this);
QPushButton*quit=newQPushButton("Quit",this);
connect(server,SIGNAL(newConnect()),SLOT(newConnect()));
connect(quit,SIGNAL(clicked()),qApp,SLOT(quit()));
}
~ServerInfo()
{
}
privateslots:
voidnewConnect()
{
infoText->append("Newconnection\n");
}
4.4猜字游戏服务器端的交叉编译
在编译基于ARM开发板的Qt应用程序时,请检查qt_toolchain工具链是否已经安装到/opt/xscalev1/arm-linux或/usr/local/arm-linux目录下。
如果没有安装。
则从教学服务器下复制arm-linux-toolchain.tar.gz压缩包到虚拟机的/opt/xscalev1或/usr/local目录下解压缩。
然后写一个脚本文件(qt_configure)来配置一个编译环境,脚本文件内容如下:
exportQTDIR=/opt/xscalev1/arm-linux/qt_toolchain/qt-2.3.7
exportQPEDIR=/opt/xscalev1/arm-linux/qt_toolchain/qtopia-free-1.7.0
exportLD_LIBRARY_PATH=/opt/xscalev1/arm-linux/qt_toolchain/qt-2.3.7/lib:
$LD_LIBRARY_PATH
exportLD_LIBRARY_PATH=/opt/xscalev1/arm-linux/qt_toolchain/qt-2.3.2/lib:
$LD_LIBRARY_PATH
exportTMAKEDIR=/opt/xscalev1/arm-linux/qt_toolchain/tmake-1.11
exportTMAKEPATH=/opt/xscalev1/arm-linux/qt_toolchain/tmake-1.11/lib/qws/linux-arm-g++
exportPATH=/opt/xscalev1/arm-linux/qt_toolchain/tmake-1.11/bin:
$PATH
用如下的命令激活脚本配置。
[root@localhostSocket]$sourceqt_configure或
[root@localhostSocket].qt_configure
由于qtopia-free-1.7.0包存在bug(编译含textedit等组件的程序出错),所以如果用到该组件时请将/opt/xscalev1/arm-linux/qt_toolchain/qtopia-1.7.0/src/applications/textedit/qtextedit.h文件复制到/opt/xscalev1/arm-linux/qt_toolchain/qtopia-1.7.0/include目录下。
这样仅保证编译成功且可以运行,但textedit组件的功能并没有实现!
基于系统中文支持有限的原因,在用QT设计器设计程序界面时不要使用中文。
否则编译时会发生一些错误;另外,目标板上支持的中文字体也较少。
由于嵌入式平台中无法对ui界面文件进行编译,除了将ui界面文件转换为标准的C++文件之外,还要对利用Qt集成开发平台生成的工程文件进行修改,否则无法编译,Qt集成开发平台生成的原始工程文件Socket.pro内容为:
SOURCES+=main.cpp\
Socket.cpp
HEADERS+=Socket.h
unix{
UI_DIR=.ui
MOC_DIR=.moc
OBJECTS_DIR=.obj
}
TEMPLATE=app
CONFIG+=qtwarn_onrelease
LANGUAGE=C++
修改后的工程文件内容为(黑体部分为新增内容,用于支持qtopia):
SOURCES+=main.cpp\
Socket.cpp
HEADERS+=Socket.h
TEMPLATE=app
CONFIG+=qtopiaqtwarn_onrelease
LANGUAGE=C++
工程文件修改后,然后利用tmake工具生成用于编译应用程序的Makefile文件。
[root@localhostSocket]$tmake–oMakefileSocket.pro
用文本编辑器打开Makefile文件,在LIBS项的最后加上–lts;例如:
LIBS=$(SUBLIBS)–L$(QPEDIR)/lib–L$(QTDIR)/lib–lm–lqpe–lqtopia–lqte-lts
[root@localhostSocket]$make
编译后,可用file命令查看编译的应用程序格式,如图6-7所示
图6-7基于ARM的Qt应用程序编译界面
5、调试分析
1.在本次大作业设计实现的过程中遇到了很多问题,首先由于个人c++语言不强,对C++编程不熟悉,导致在开发过程中遇到了很大的困难。
2.其次,在之前的交叉编译环境搭建的实验中,有些方法方式掌握不够,导致在这次设计的交叉编译过程中,遇到一些问题
3.当然,虽然可能最后自己没有完全凭自己的个人能力实现TCPSocket猜字游戏,但这次的程序设计也让我更加深刻的接触到QT的TCP,SOCKET编程
6、测试结果
7、参考文献
【3】魏红兴嵌入式系统设计清华大学出版社
【4】郭春柱嵌入式系统设计案例导学西安电子科技大学出版社
【5】郑灵翔,北京航空航天大学出版社,2008:
【6】李善平、郑扣根,《Linux内核分析和实验教程》,机械工业出版社,1999