QT5.5.0实现TCP网络通信
创建TCP服务器
1.实例化QTCPSocket和QTCPServer
//创建了一个MyTCPServer类,定义了一个获取IP的方法
//其基类为QTcpServer
class MyTCPServer : public QTcpServer
{
Q_OBJECT
public:
explicit MyTCPServer(QObject *parent = 0);
void GetLocalIP(QList<QHostAddress> &IPList,QStringList &ipshow);
signals:
public slots:
};
//创建一个QTcpSocket对象
tcp_socket = new QTcpSocket(this);
//创建一个MyTCPServer对象
tcp_server = new MyTCPServer(this);
2.检测IP连接
void MyTCPServer::GetLocalIP(QList<QHostAddress> &IPList,QStringList &ipshow)
{
//获取本机IP地址列表
QList<QNetworkInterface> list=QNetworkInterface::allInterfaces();
foreach (QNetworkInterface interface, list) {
QList<QNetworkAddressEntry> entrylist=interface.addressEntries();
//只使用IPV4地址
foreach (QNetworkAddressEntry entry, entrylist) {
if(entry.ip().protocol()==QAbstractSocket::IPv4Protocol)
{
IPList<<entry.ip();
ipshow<<entry.ip().toString();
}
}
}
}
3.TCP服务器具有监听功能,能够与其他的客户端建立连接
void Widget::startListen()
{
if(ui->addressbox->currentIndex()!=-1)
{
qDebug()<<"Start listening";
//使用QTcpServer下的listen开启监听
tcp_server->listen(IPList[ui->addressbox->currentIndex()],ui->portbox->currentText().toShort());
ui->textBrowser->append("The server ip is "+ui->addressbox->currentText());
ui->textBrowser->append("The server is listening port "+ui->portbox->currentText());
}
}
4.QTCPServer提供了新客户端连接的信号,当有新用户连接时能够自动触发该信号,我们通过该信号执行客户端连接槽函数
//客户端信号槽连接
connect(tcp_server,&MyTCPServer::newConnection,this,&Widget::clientConnected);
//槽函数
void Widget::clientConnected()
{
qint16 port;
QString ip;
//新客户端连接将返回一个QTCPSocket类型,当服务器被摧毁时他会被自动释放
tcp_socket = tcp_server->nextPendingConnection();
ip = tcp_socket->peerAddress().toString();
port = tcp_socket->peerPort();
ui->textBrowser->append("Client connected");
ui->textBrowser->append("The ip address is"+ip);
ui->textBrowser->append("The port number is "+ QString::number(port));
//接收消息就绪信号,当接收到客户端发送的消息时出触发该信号
//在槽函数内处理接收的数据,特别注意该连接调用的位置,该连接调用必须在nextPendingConnection()之后否则会出现无法接收客户端数据的问题
//初步理解是只有当新的客户端连接之后再调用QTCPSocket的该连接才生效
connect(tcp_socket,&QTcpSocket::readyRead,this,&Widget::reciveMessage);
//这里的连接同样如此
connect(tcp_socket,&QTcpSocket::stateChanged,this,&Widget::tcpStateChange);
}
5.接收数据槽函数
void Widget::reciveMessage()
{
//接收通过tcp_socket中的readAll()方法实现
QString message="Client:"+tcp_socket->readAll();
ui->textBrowser->append(message);
}
6.发送槽函数
void Widget::sendMessage()
{
if(NULL==tcp_socket)
return;
if(tcp_socket->state()==tcp_socket->ConnectedState)
{
ui->textBrowser->append("Server:"+ui->sendedit->toPlainText());
//发送数据通过tcp_socket中的write方法实现
tcp_socket->write(ui->sendedit->toPlainText().toLatin1());
}
}
创建TCP客户端
1.TCP客户端需要选择服务器地址以及端口号,然后请求建立连接。
void Widget::toConnect()
{
if(tcp_socket->state()!=tcp_socket->ConnectedState)
{
//客户端地址,暂时先通过直接设定
IPList[ui->addressbox->currentIndex()]="192.168.1.17";
qDebug()<<IPList[ui->addressbox->currentIndex()]<<ui->portbox->currentText();
//通过tcp_socket中的connectToHost与服务器进行连接
tcp_socket->connectToHost(IPList[ui->addressbox->currentIndex()],ui->portbox->currentText().toShort());
}
}
2.检测连接状态
void Widget::tcpStateChange(QAbstractSocket::SocketState state)
{
switch (state) {
case QAbstractSocket::UnconnectedState:
ui->textBrowser->append("Socket state:UnconnectedState");
break;
case QAbstractSocket::ConnectedState:
ui->textBrowser->append("Socket state:ConnectedState");
break;
case QAbstractSocket::ConnectingState:
ui->textBrowser->append("Socket state:ConnectingState");
break;
case QAbstractSocket::ListeningState:
ui->textBrowser->append("Socket state:ListeningState");
break;
default:
break;
}
}
3.客户端的发送和接收消息与服务器端一样