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; }
运行效果截图:
相关文章推荐
- 基于Socket编程,模拟TCP部分协议字段编程
- 计算机网络Socket编程之TCP协议
- Socket编程——基于TCP实现自己的通信协议
- socket编程 通讯协议tcp,数据承载协议http
- 网络层、传输层、应用层、端口通信协议编程接口 - http,socket,tcp/ip 网络传输与通讯知识总结
- 黑马程序员--图形界面中的鼠标,键盘两个事件,做一个磁盘的文件列表,菜单,子菜单,模拟记事本。网络编程,TCP的通信协议的特点
- Java系列-Socket网络编程,TCP/IP和Http等网络协议理解
- 如何在socket编程的Tcp连接中实现心跳协议
- 如何在socket编程的Tcp连接中实现心跳协议
- 使用QTcpSocket和QTcpServer进行TCP编程
- Socket编程下篇-----TCP协议的C/S案例
- Socket编程------模拟QQ聊天(TCP)
- socket编程 -- 基于TCP协议的C/S通信模型及实现
- QT TCP下的socket编程
- 基于TCP/IP和UDP协议的socket编程结构解析
- 网络协议(二)Socket编程之TCP
- 简单的TCP协议 socket编程(C语言版服务器和客户端)
- 基于TCP协议之——socket编程
- 计算机网络Socket编程之TCP协议
- Socket网络编程,TCP/IP和Http等网络协议理解