qt 使用网络模块,需要在.pro文件添加 Qt += network
主机信息查询
QHostInfo类重要的函数
获取主机名:
static QString localHostName(); //静态函数,这个是获取本机的信息
获取主机ip地址 :
static QHostInfo fromName(const QString &name);//静态函数
再通过QHostInfo可以获取ip地址列表
QList<QHostAddress> addresses() const;
还可以调用QString hostName() const;获取主机名字
QHostAddress 在qt中以QHostAddress 方式显示ip地址,其有很多转换函数,
explicit QHostAddress(quint32 ip4Addr);
explicit QHostAddress(const QString &address);
explicit QHostAddress(const sockaddr *address);
QString toString() const; //转成QString
quint32 toIPv4Address() const;
如果是其他主机的信息,可以通过下面的函数
static int lookupHost(const QString &name, QObject *receiver, const char *member); //异步方式
receiver: 响应槽函数的接收者
member:槽函数
主机的网络接口信息(即网卡):QNetworkInterface
static QList<QNetworkInterface> allInterfaces();//获取主机所有的网卡信息列表
QString name() const;
QString humanReadableName() const;//网卡名称
QString hardwareAddress() const; //硬件地址,即mac地址
QList<QNetworkAddressEntry> addressEntries() const; //获取网络接口信息,一个网络可以包含多个ip地址
在QNetworkAddressEntry类中的重要函数
QHostAddress ip() const;
QHostAddress netmask() const;
QHostAddress broadcast() const;
udp
使用QUdpSocket , QUdpSocket : public QAbstractSocket
绑定:bool bind(const QHostAddress &address, quint16 port = 0, BindMode mode = DefaultForPlatform);
加入组播:bool joinMulticastGroup(const QHostAddress &groupAddress, const QNetworkInterface &iface);
bool joinMulticastGroup(const QHostAddress &groupAddress);
退出组播 :bool leaveMulticastGroup(const QHostAddress &groupAddress, const QNetworkInterface &iface);
bool leaveMulticastGroup(const QHostAddress &groupAddress);
设置属性: virtual void setSocketOption(QAbstractSocket::SocketOption option, const QVariant &value);
如:接收发送缓冲区大小,广播、KeepAliveOption
setSocketOption(QAbstractSocket::MulticastTtlOption,1);
//Multicast路由层次,1表示只在同一局域网内 //组播TTL: 生存时间,每跨1个路由会减1,多播无法跨过大多数路由所以为1 //默 认值是1,表示数据包只能在本地的子网中传送。
发送: qint64 writeDatagram(const char *data, qint64 len, const QHostAddress &host, quint16 port);
缓冲区队列可以设置为QByteArray,方便转换。
接收:qint64 readDatagram(char *data, qint64 maxlen, QHostAddress *host = Q_NULLPTR, quint16 *port = Q_NULLPTR);
在接收前加上判断函数是否有接收的数据:bool hasPendingDatagrams() const;
接收数据的大小:qint64 pendingDatagramSize() const;
接收的信号:void readyRead();
获取状态的变化:void stateChanged(QAbstractSocket::SocketState);
void abort(); //立即终止连接,丢掉还未发送的数据 在udp退出时需用到这个韩式强行终止。
对于new 出来的套接字,关闭时应该delete,
TCP
服务端:
有两个类来实现:
1.QTcpServer QTcpServer : public QObject 监听套接字 只有服务端的监听套接字才使用到
2.QTcpSocket QTcpSocket : public QAbstractSocket //接收发送套接字
QTcpServer 类的函数
1.绑定,开始监听 bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0); 而不是bind.
2.绑定的端口 :quint16 serverPort() const;
3.绑定的地址:QHostAddress serverAddress() const;
4.判断绑定状态:bool isListening() const;
5.关闭绑定,关闭监听动作:void close(); //套接字还是存在的 相当于closesocket()函数。tcp使用这个函数关闭连接。
6.连接:当有新的客户端连接时(客户端调用connectToHost),QTcpServer 内部的incomingConnection函数(虚函数,自动调用的)会创建一个与客户端连接的QTcpSocket对象,然后QTcpServer 对象发射信号 void newConnection();在该信号对应的槽函数调用nextPendingConnection接收客户端的连接,然后使用QTcpSocket进行通讯。
QTcpSocket类的函数
7.接收:缓冲区有新数据,会发射信号void readyRead();在该信号对应的槽函数实现接收数据
socket之间的数据通讯协议有两种方式:基于行或基于数据块。
a.基于行:一般是纯文本,每一行以一个换行符结束。canreadline判读是否有新一行的数据需要读取,readline读取一行数据。
b.基于数据块,自定义的格式,和以前其他的一样
qint64 readData(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
qint64 readLineData(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
或
qint64 read(char *data, qint64 maxlen);
qint64 readLine(char *data, qint64 maxlen);
8.发送: //发送就没有line行的做法,可以通过加\n 实现
qint64 writeData(const char *data, qint64 len) Q_DECL_OVERRIDE;
qint64 write(const char *data, qint64 len);
9.关闭:
a. QTcpSocket 关闭:调用deleteLater();
b. QTcpServer 关闭:调用void close(); 对new 出来的,应该还需调用delete.
客户端:
只使用一个套接字:QTcpSocket
1.连接服务端: virtual void connectToHost(const QHostAddress &address, quint16 port, OpenMode mode = ReadWrite);//异步方式,连接成功会发射connected()信号
2.断开连接服务端: virtual void disconnectFromHost();//断开socket,关闭成功后发射disconnected()信号,tcp客户端使用该函数关闭连接
3.如果要使用阻塞方式连接服务器,则使用virtual bool waitForConnected(int msecs = 30000);阻塞运行,直到连接成功或失败。