您的位置:首页 > 编程语言 > Qt开发

QT-Socket编程之模拟TCP五层协议解/封装

2017-01-16 17:15 483 查看

消息封/解装仿真系统的设计与实现

基本要求

按照TCP五层模型仿真消息在两台主机间的通信过程(见下图):



(1)在发送端模拟数据从高层到低层的封装过程,在接收端模拟数据从低层到高层的解封装过程;

(2)按照每层的功能对数据填加报头,并显示每一层得到的封/解装格式;

(3)传输层和网络层的封装格式参考TCP/IP的相应各层协议格式;

(4)网络层的IP报文需要模拟报文分段和重组的过程;

(5)数据链路层帧格式参考局域网的MAC帧格式;

(6)物理层显示为0或1比

首先要在QT里面进行Socket编程,必须在QT创建的项目文件开始添加:

QT += core gui network



客户端:

先在client.h头文件中引入 #include <QtNetwork>,创建客户端通信套接字

QTcpSocket *c_socket; //客户端通信套接字


在client.cpp文件中实现:

void client::on_Connect_clicked()
{
QString ip = ui->IP->text();
qint16 port = ui->Port->text().toInt();
if(ip.isEmpty() == true || port == 0)
{
QMessageBox::warning(this, "警告", "IP或端口不能为空");
return;
}
c_socket->abort();//断开所有连接
c_socket->connectToHost(QHostAddress(ip),port);//127.0.0.1"代表主机
bool connected = c_socket->waitForConnected();
if(connected){

OkConnection();
}
}

//点击发送按钮
void client::on_Send_clicked()
{
QString message = ui->message->text();//获取发送框内数据
if(message != "")
{
QString buf = message;
c_socket->write(buf.toUtf8().data());//发送到服务器
}
else
{
QMessageBox::warning(this, "发送", "发送数据为空!");
return;
}
}




服务器:

先在server.h头文件中引入 #include <QtNetwork>,创建客户端通信套接字

QTcpServer *s_listen;//服务器监听套接字
QTcpSocket *s_socket;//服务器通信套接字


在server.cpp文件中实现:

newListen();
connect(s_listen, SIGNAL(newConnection()), this, SLOT(acceptConnection()));
}

//接受读取消息
void server::revdata()
{
QString datas = s_socket->readAll();
}

//监听
void server::newListen()

{
//监听是否有客户端来访,且对任何来访者监听,端口为11111
if(!s_listen->listen(QHostAddress::Any,SERVER_PORT))
{
QMessageBox::warning(this, "监听", "监听失败!");
return;
}
}

//接受连接
void server::acceptConnection()
{
QMessageBox::information(this, "连接状态", "连接成功!");
ui->send->setEnabled(true);
s_socket = s_listen->nextPendingConnection();
connect(s_socket, SIGNAL(readyRead()), this, SLOT(revdata()));
}


封装

PS:详细协议内容自行参考相关资料

commondata.cpp:

#include "commondata.h"
#define BUF_SIZE 16
QString AppLayer(QString msg)
{

QString tmp;
QString header = "AppHeader";//TCP头
tmp = header + '#' + msg;
return tmp;
}

QString TransLayer(QString msg)
{

QString tmp;
QString TCPheader;

//0-15bit Source Port
QString SourcePort = "0000000011111111";
//16-31bit Destination Port 11111
QString DesPort = "0010101101100111";
//32bits Sequence Number
QString SequenceNum = "00000000000000000000000000001011";
//32bits Acknowledgement Number
QString AckNum = "00000000000000000000000011111011";
//4bits Header Length
QString HeaderLength = "0101";
//6bits Reserved
QString Reserved ="000000";
//URG;ACK;PSH;RST;SYN;FIN
QString Flag = "000000";
//16bits Window Size
QString Windowsize = "0000000000000111";
//16bits Checksum
QString CheckSum = "0101010101010010";
//16bits UrgentPointer
QString UrgentP = "0000000000001111";
TCPheader = SourcePort + DesPort + SequenceNum + AckNum + \
HeaderLength + Reserved + Flag + Windowsize + CheckSum + UrgentP;
tmp = TCPheader + "#" + msg;
return tmp;
}

QString NetLayer(QString msg)
{
QString tmp;
QString NetHeader;

QString VER = "0100"; //4bits
QString HLEN = "1111";//4bits
QString Service = "00000000";//8bits
QString totalLenth = "0101010101010101";//16bits
QString Identification = "0000000000000000";//16bits
QString Flag = "000";//3bits
QString FragmentationOffset = "0000000000000";//13bits
QString TTL = "00000000"; //8bits,time to live
QString Protocol = "00000000";//8bits
QString HeaderChecksum = "0000000000000000";//16bits
QString SourIPAddress = "00000000000000000000000000000000";//32bits
QString DestinationIPAddress = "00000000000000000000000000000000";//32bits
QString Option = "";
NetHeader = VER + HLEN + totalLenth + Identification +\
Flag + FragmentationOffset + TTL + Protocol + HeaderChecksum + SourIPAddress + DestinationIPAddress + Option;
tmp = NetHeader + '#' + msg;
return tmp;

}

QString LinkLayer(QString msg)
{
QString tmp;
QString FrameFlag1 = "00001111"; // 8bits
QString FrameAdd = "11101011";//8bits
QString FrameControl = "01111000";//8bits
QString FrameData = msg ;
QString FrameFCS = "1010010101011000";//16bits
QString FrameFlag2 = "10110101";//8bits
tmp = FrameFlag1 + FrameAdd + FrameControl + '#' + FrameData + '#' + FrameFCS + FrameFlag2;
return tmp;

}

QString PhyLayer(QString msg)
{
QString tmp;
QString Phyheader = "PhyHeader";//

tmp = Phyheader + '#' + msg;
return tmp;

}


运行效果截图:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: