ZLToolkit 初始化
只作为发送方
初始化:
Socket::Ptr m_SockRecv;
this->m_SockRecv = Socket::createSocket(nullptr, false);
this->m_SockRecv->bindUdpSock(8003,“192.168.172.11”); //这里特别注意,win下一定要绑定本地IP地址192.168.172.11,不然多个网卡的系统会无法发送数据,linux下可以不绑定本地ip也可以成功发送数据;由于是只作为发送方,可以将绑定端口号设置为组播端口号以外的值,组播端口为8002。
这样就完成了ZLToolkit的初始化操作,下面就可以进行发送数据了。
m_SoundSignalAddr = toolkit::SockUtil::make_sockaddr(“239.0.0.2”, 8002); //这个地址ip为组播地址如:239.0.0.2,port为组播端口号:8002
this->m_SockRecv->send(data.data(),data.size(),(struct sockaddr *) &m_SoundSignalAddr, sizeof(struct sockaddr_in));
只作为接收方
初始化:
Socket::Ptr m_SockRecv;
this->m_SockRecv = Socket::createSocket(nullptr, false);
win32: this->m_SockRecv->bindUdpSock(8002,“192.168.172.11”);
linux: this->m_SockRecv->bindUdpSock(8002); //这里特别注意,win下一定要绑定本地IP地址192.168.172.11,不然多个网卡的系统会无法接收数据;linux下相反,一定要不绑定本地ip,不然无法接收数据;由于是只作为接收方,必须将绑定端口号设置为组播端口号,组播端口:8002。
接着进行加入组播设置:
this->fd = this->m_SockRecv->rawFD();
SockUtil::setMultiTTL(this->fd); //设置TTL
SockUtil::setMultiIF(this->fd,“192.168.172.11”); //设置组播发送网卡
SockUtil::setMultiLOOP(this->fd,false);//设置不接收本地发送组播数据
SockUtil::joinMultiAddr(this->fd,“239.0.0.2”,“192.168.172.11”); //加入组播
这样就完成了ZLToolkit的初始化操作,下面就可以正常接收数据了。
既作为接收方又作为发送方
初始化:
Socket::Ptr m_SockRecv;
this->m_SockRecv = Socket::createSocket(nullptr, false);
win32: this->m_SockRecv->bindUdpSock(8002,“192.168.172.11”);
linux: this->m_SockRecv->bindUdpSock(8002); //这里特别注意,win下一定要绑定本地IP地址192.168.172.11,不然多个网卡的系统会无法发送/接收数据;linux下相反,一定要不绑定本地ip,不然无法发送/接收数据;由于既接收又发送,必须将绑定端口号设置为组播端口号,组播端口:8002。
接着进行加入组播设置:
this->fd = this->m_SockRecv->rawFD();
SockUtil::setMultiTTL(this->fd); //设置TTL
SockUtil::setMultiIF(this->fd,“192.168.172.11”); //设置组播发送网卡
SockUtil::setMultiLOOP(this->fd,false);//设置不接收本地发送组播数据
SockUtil::joinMultiAddr(this->fd,“239.0.0.2”,“192.168.172.11”); //加入组播
这样就可以发送、接收组播数据了。
完整示例代码只有一个类UdpClient
udpclient.h 如下:
#ifndef _UDPCLIENT_H_
#define _UDPCLIENT_H_
#include <QObject>
#include <qglobal.h>
#include <QLibrary>
#include <QMutex>
#include <QSharedPointer>
#include "Network/Socket.h"
#ifdef WIN32
#include "pcap_windows_include/pcap.h"
#else
#include "pcap_linux_include/pcap.h"
#include <semaphore.h>
#endif
//extern int pcap_data_valid_index;
using namespace toolkit;
typedef std::function<void(const SockException &err)> TErrCallback ;
typedef std::function<void(const Buffer::Ptr& buffer, struct sockaddr* addr, int addr_len)> TRecvDataCallback ;
class UdpClient : public QObject
{
Q_OBJECT
public:
UdpClient(int bind_port,QString bind_ip,QObject *parent = nullptr);
UdpClient(QObject *parent = nullptr);
~UdpClient();
protected:
int m_OwnBindPort; //本地绑定端口
QString m_OwnBind_Ip; //本地绑定IP
Socket::Ptr m_SockRecv; //本地sock
int fd; //socket fd
struct sockaddr_storage m_SoundSignalAddr;//声信号处理机sock结构体
uint64_t m_all_send_lost_number = 0;
uint64_t m_all_send_number = 0;
private:
void makeAddr(struct sockaddr* out, const char* ip, uint16_t port);
TErrCallback m_ErrCallback;
TRecvDataCallback m_RecvDataCallback;
private slots:
void init();
void onError(const SockException &err);
void onRecvData(const Buffer::Ptr& buffer, struct sockaddr* addr, int addr_len);
public slots:
bool setIP_and_Port(QString strIP,unsigned short port); //获取IP地址和端口号
void enableRecv(bool b_recv);//停止/开始接收数据
void sendData(const QString &ip, int port, QByteArray);
void setMulticastParam(QString multicast);
virtual void initNetData();
virtual void onRecv(QByteArrayList list);
virtual void onRecvByte(QString src_ip,int dst_port,QByteArray arr);
virtual void start();
signals:
void toReceiveData(QByteArray buffer);
};
#endif
udpclient.cpp 如下:
#include "qhelperdata.h"
#include "appconfig.h"
#include "udpclient.h"
#include "Util/util.h"
#include "Util/logger.h"
#include <QDebug>
#include "pcapmodule.h"
UdpClient::UdpClient(int bind_port,QString bind_ip,QObject *parent):QObject(parent)
{
this->m_OwnBindPort = bind_port;
this->m_OwnBind_Ip = bind_ip;
init();
}
UdpClient::UdpClient(QObject *parent):QObject(parent)
{
init();
}
UdpClient::~UdpClient()
{
this->m_SockRecv.reset();
}
void UdpClient::enableRecv(bool b_recv)
{
this->m_SockRecv->enableRecv(b_recv);
}
void UdpClient::makeAddr(struct sockaddr *out, const char* ip, uint16_t port)
{
struct sockaddr_in &servaddr = *((struct sockaddr_in*)out);
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(port);
servaddr.sin_addr.s_addr = inet_addr(ip);
bzero(&(servaddr.sin_zero), sizeof servaddr.sin_zero);
}
void UdpClient::sendData(const QString &ip, int port, QByteArray data)
{
m_SoundSignalAddr = toolkit::SockUtil::make_sockaddr(ip.toStdString().c_str(), port);
m_all_send_number++;
if(-1 == this->m_SockRecv->send(data.data(),data.size(),(struct sockaddr *) &m_SoundSignalAddr, sizeof(struct sockaddr_in)))
{
m_all_send_lost_number++;
AppConfig::append(TIPS, QString("----------发送失败总包数:%1----------发送失败率:%2--------").arg(m_all_send_lost_number).arg((m_all_send_lost_number*1.000000/(m_all_send_number)*1000000)));
}
}
void UdpClient::setMulticastParam(QString multicast)
{
this->fd = this->m_SockRecv->rawFD();
SockUtil::setMultiTTL(this->fd);
SockUtil::setMultiIF(this->fd,this->m_OwnBind_Ip.toStdString().c_str());
SockUtil::setMultiLOOP(this->fd,false);
SockUtil::joinMultiAddr(this->fd,multicast.toStdString().c_str(),this->m_OwnBind_Ip.toStdString().c_str());
}
void UdpClient::init()
{
QMutexLocker locker(&AppConfig::pcap_mutex);
this->m_SockRecv = Socket::createSocket(nullptr, false);
}
void UdpClient::initNetData()
{
if(true == this->m_SockRecv->bindUdpSock(this->m_OwnBindPort+1/*,this->m_OwnBind_Ip.toStdString()*/))
{
}
else
{
QThread::sleep(1);
AppConfig::append(WRONG, QString("------------------------------this->m_SockRecv->bindUdpSock(this->m_OwnBindPort = 1%,this->m_OwnBind_Ip.toStdString() = 2%) is false.").arg(this->m_OwnBindPort).arg(this->m_OwnBind_Ip));
return;
}
this->m_ErrCallback = std::bind(&UdpClient::onError, this, std::placeholders::_1);
this->m_SockRecv->setOnErr(this->m_ErrCallback);
this->m_RecvDataCallback = std::bind(&UdpClient::onRecvData, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
this->m_SockRecv->setOnRead(this->m_RecvDataCallback);
}
void UdpClient::onRecv(QByteArrayList list)
{
}
void UdpClient::onRecvByte(QString src_ip, int dst_port, QByteArray arr)
{
}
void UdpClient::start()
{
}
void UdpClient::onRecvData(const Buffer::Ptr& data, struct sockaddr* addr, int addr_len)
{
//qDebug() << "你好"/*QByteArray(data->data(), data->size()).toHex().toUpper()*/ <<endl;
QByteArray arr = QByteArray(data->data(), data->size());
qDebug() << arr <<endl;
emit toReceiveData(QByteArray(data->data(), data->size()));
}
bool UdpClient::setIP_and_Port(QString strIP,unsigned short port)
{
this->m_OwnBindPort = port;
this->m_OwnBind_Ip = strIP;
return true;
}
void UdpClient::onError(const SockException &err)
{
AppConfig::append(3, err.what());
}
本实例已经上传到我的资源