QT += network //加入网络模块
#include //建立Tcp通信应用程序
#include //建立Tcp通信套接字
QTcpServer *server; //Tcp服务器监听套接字
QTcpSocket *socket; //Tcp服务器通信套接字
QTcpSocket *client; //Tcp客户端
network::network(QWidget *parent) :
QWidget(parent),
ui(new Ui::network)
{
ui->setupUi(this);
server = new QTcpServer(this); //Tcp服务器监听套接字
socket = new QTcpSocket(this); //Tcp服务器通信套接字
socket = NULL;
client = new QTcpSocket(this); //创建一个客户端
Get_LocalIp(); //获取本地IP地址
//未连接时失能 发送 按钮
ui->TcpServersend_button->setEnabled(false);
ui->tcpclientsend_button->setEnabled(false);
}
//获取本地Ip
void network::Get_LocalIp()
{
QString hostName=QHostInfo::localHostName(); //本地主机名
QHostInfo hostInfo=QHostInfo::fromName(hostName); //本机IP地址
QList addList=hostInfo.addresses(); //IP地址列表
for (int i=0;itcplisen_ip->setText(aHost.toString()); //显示出Ip地址
break;
}
}
}
void network::on_tcplisten_Button_clicked()
{
if(server->isListening()==true) //若服务器正在监听
{
if(socket !=NULL) //判断是否已有客户端连接
socket->disconnectFromHost(); //断开与客户端的连接
server->close(); //关闭服务器
QString str = "停止监听成功"; //消息框提示信息
ui->TcpServer_receive->append(str);
ui->tcplisten_Button->setText("监听"); //改变按钮的提示文字
ui->LisenState->setText("已停止监听"); //状态栏改变连接状态
disconnect(server , &QTcpServer::newConnection , this , &network::deal_NewConnection);
}
else //若服务器未监听
{
quint16 port=ui->tcplisen_port->text().toInt(); //获取监听的端口号
QString ip = ui->tcplisen_ip->text(); //获取监听的Ip
server->listen(QHostAddress(ip),port); //监听 设置的Ip
// server->listen(QHostAddress::Any,port); //监听 所有的Ip
ui->tcplisten_Button->setText("停止"); //改变按钮的提示文字
ui->LisenState->setText("正在监听"); //状态栏改变连接状态
//建立连接时会发送 newConnection 信号,关联对应的处理槽函数
connect(server , &QTcpServer::newConnection , this , &network::deal_NewConnection);
}
}
void network::deal_NewConnection()
{
//获取通信套接字
socket = server->nextPendingConnection();
//获取对方的IP地址 端口号
QString ip = socket->peerAddress().toString();
quint16 port = socket->peerPort();
//消息框提示连接成功
QString package = QString("[%1:%2] 成功连接").arg(ip).arg(port);
ui->TcpServer_receive->append(package);
ui->SocketState->setText("Connected");
// 关联接受到客户端消息时的处理槽函数
connect(socket , &QTcpSocket::readyRead , this , &network::deal_readyRead);
//关联断开连接时的处理槽函数
connect(socket , &QTcpSocket::disconnected , this, &network::deal_disconnect);
//使能发送按钮
ui->TcpServersend_button->setEnabled(true);
}
/*
* 若设置为监听所有ip 则获得的 ip 格式为 "::ffff:xxx.xxx.xxx.xxx"
* 可通过 ip = ip.mid(7); 来截取指定位置字符 ,使得 ip = "xxx.xxx.xxx.xxx"
*
* 若设置为监听特定ip 则获得的 ip 格式为 "xxx.xxx.xxx.xxx"
*/
void network::deal_readyRead()
{
QString ip = socket->peerAddress().toString(); // 获取客户端 IP地址
quint16 port = socket->peerPort(); // 获取客户端 端口号
QString data = socket->readAll().data(); // 获取客户端 发来的数据
// 数据打包 显示
data = QString("[%1:%2] \n%3").arg(ip).arg(port).arg(data);
ui->TcpServer_receive->append(data);
}
void network::deal_disconnect()
{
//消息框提示
QString ip = socket->peerAddress().toString();
quint16 port = socket->peerPort();
QString package = QString("[%1:%2] 已断开").arg(ip).arg(port);
ui->TcpServer_receive->append(package);
//状态栏信息更新
ui->SocketState->setText("Disconnected");
ui->TcpServersend_button->setEnabled(false);
socket->close();
}
void network::on_connectserver_Button_clicked()
{
if(client->state()==QAbstractSocket::UnconnectedState) //与服务器未连接
{
QString ip = ui->serverIp_Edit->text(); //获取要连接的服务器IP
quint16 port = ui->serverport_Edit->text().toInt(); //获取要连接的服务器端口号
client->connectToHost(QHostAddress(ip),port); //主动和服务器建立连接
if(client->waitForConnected(2000)==true) //等待与服务器建立连接 等待2s
{
QString str="成功和服务器连接";
ui->TcpClient_receive->append(str);
ui->connectState->setText("已连接");
ui->connectserver_Button->setText("断开");
ui->tcpclientsend_button->setEnabled(true);
connect(client , &QTcpSocket::readyRead, this , &network::deal_ClientRead);
connect(client,&QTcpSocket::disconnected,this,&network::deal_Clientdisconnect); //
}
else //连接失败
{
QString str="和服务器连接失败";
ui->TcpClient_receive->append(str);
}
}
else if(client->state()==QAbstractSocket::ConnectedState) //与服务器已连接
{
client->disconnectFromHost(); //主动与服务器断开连接
}
}
void network::deal_ClientRead()
{
//获取接收到的数据
QString data = client->readAll().data();
//获取IP地址
QString ip = client->peerAddress().toString();
//获取端口号
quint16 port = client->peerPort();
data = QString("[%1:%2] \n%3").arg(ip).arg(port).arg(data);
ui->TcpClient_receive->append(data);
}
void network::deal_Clientdisconnect()
{
client->close();
QString str="成功和服务器断开";
ui->TcpClient_receive->append(str);
ui->connectState->setText("已断开");
ui->connectserver_Button->setText("连接");
ui->tcpclientsend_button->setEnabled(false);
// 断开信号和槽的关联
disconnect(client , &QTcpSocket::readyRead, this , &network::deal_ClientRead);
disconnect(client,&QTcpSocket::disconnected,this,&network::deal_Clientdisconnect);
}
void network::on_tcpclientsend_button_clicked()
{
QString data = ui->TcpClient_send->toPlainText(); //获取发送的内容
client->write(data.toUtf8().data()); // 发送
}
void network::on_clear_clientReceive_clicked()
{
ui->TcpClient_receive->clear();
}
void network::on_clear_clientSend_clicked()
{
ui->TcpClient_send->clear();
}