#ifndef _MULTI_NET_UTIL_H__
#define _MULTI_NET_UTIL_H__
#include <iostream>
#include <vector>
#include <map>
#ifdef WIN32
#include <WinSock2.h>
#else
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <stdint.h>
#include <pthread.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <syslog.h>
#include <dirent.h>
#include <sys/time.h>
#include <sys/socket.h>
#endif
#ifdef WIN32
#define OUT_CLASS
#ifdef OUT_CLASS
#define OUT_EX_CLASS _declspec(dllexport)
#else
#define OUT_EX_CLASS _declspec(dllimport)
#endif
#endif
class UDPNetShare;
typedef struct _CIPInfo {
std::string strIP;
int nPort;
int nChannel;
_CIPInfo()
{
strIP = "";
nPort = 5000;
nChannel = 0;
}
}CIPPort;
typedef struct _DataInfo{
int nChannel;
char* pBuf;
int nSize;
}DataInfo;
#ifdef WIN32
class OUT_CLASS MultiNetUtil
#else
class MultiNetUtil
#endif
{
public:
//传入本地绑定接口
MultiNetUtil();
~MultiNetUtil();
bool InitSocket(int nPort);
public:
bool AddIpPort(std::string strIp, int nPort, int nChannel);
int PushData(int nChannel, int nTotalSize, char* pBuf);
bool SetSleepTime(int nTime) { m_nTime = nTime; return true; }
private:
//服务器需要向这些ip或者端口发送消息
std::vector<CIPPort> m_arrIPPort;
int m_nTime;
#ifdef WIN32
SOCKET m_sock;
#else
int m_sock;
#endif
sockaddr_in m_clientaddr;
sockaddr_in m_servaddr;
public:
std::vector<DataInfo*> m_arrData;
std::map<int, UDPNetShare*> m_mapNetUtil;
};
#ifdef WIN32
__declspec(dllexport) MultiNetUtil* createNetUtil();
#else
MultiNetUtil* createNetUtil();
#endif
#endif
#include "MultiNetUtil.h"
#include "UDPNetShare.h"
#include <pthread.h>
#include "sysfun.h"
using namespace std;
CThreadLock g_RoundLock;
#ifdef WIN32
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "pthreadVC2.lib")
#endif
MultiNetUtil::MultiNetUtil():m_nTime(3)
{
#ifdef WIN32
WSAData wsa;
WSAStartup(2, &wsa);
#endif
}
MultiNetUtil::~MultiNetUtil()
{
#ifdef WIN32
WSACleanup();
#endif
}
void* IdleRoundThread(void* pArgs)
{
MultiNetUtil* pUtil = (MultiNetUtil*)pArgs;
if (pUtil != NULL)
{
while (true)
{
if (pUtil->m_arrData.size() > 0)
{
g_RoundLock.Lock();
std::vector<DataInfo*>::iterator iterInfo = pUtil->m_arrData.begin();
std::map<int, UDPNetShare*>::iterator iterObj = pUtil->m_mapNetUtil.find((*iterInfo)->nChannel);
if (iterObj != pUtil->m_mapNetUtil.end())
{
iterObj->second->PushData((*iterInfo)->nSize, (*iterInfo)->pBuf);
cout << "nChannel:" << (*iterInfo)->nChannel << "-DataSize:" << pUtil->m_arrData.size() << "-IpPort Size:" << pUtil->m_mapNetUtil.size() << endl;
}
pUtil->m_arrData.erase(iterInfo);
nsleep(1);
g_RoundLock.UnLock();
}
else
{
nsleep(10);
}
}
}
return NULL;
}
MultiNetUtil* createNetUtil()
{
return new MultiNetUtil();
}
bool MultiNetUtil::InitSocket(int nPort)
{
m_sock = socket(AF_INET, SOCK_DGRAM, 0);
#ifdef WIN32
if (m_sock == INVALID_SOCKET)
#else
if(m_sock < 0)
#endif
{
cout << "create error " << endl;
return false;
}
m_servaddr.sin_family = AF_INET;
#ifdef WIN32
m_servaddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
#else
m_servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
#endif
m_servaddr.sin_port = htons(nPort);
if (bind(m_sock, (sockaddr*)&m_servaddr, sizeof(sockaddr)) < 0)
{
cout << "error bind" << endl;
return false;
}
//创建发送循环线程
pthread_t pid;
if (pthread_create(&pid, NULL, IdleRoundThread, this) != 0)
{
cout << "thread round create failed" << endl;
return false;
}
else
{
pthread_detach(pid);
cout << "thread round create success" << endl;
}
return true;
}
bool MultiNetUtil::AddIpPort(std::string strIp, int nPort, int nChannel)
{
CIPPort sip;
sip.nChannel = nChannel;
sip.nPort = nPort;
sip.strIP = strIp;
m_arrIPPort.push_back(sip);
//创建发送类
UDPNetShare *pShare = new UDPNetShare;
pShare->SetSleepTime(m_nTime);
pShare->InitWith(m_sock);
pShare->InitIPPort(strIp.c_str(), nPort);
m_mapNetUtil[nChannel] = pShare;
return true;
}
int MultiNetUtil::PushData(int nChannel, int nTotalSize, char* pBuf)
{
DataInfo * pData = new DataInfo;
pData->nChannel = nChannel;
pData->nSize = nTotalSize;
pData->pBuf = pBuf;
g_RoundLock.Lock();
m_arrData.push_back(pData);
g_RoundLock.UnLock();
return m_arrData.size();
}
公共函数:
#ifndef _SYS_FUN_H__
#define _SYS_FUN_H__
#ifdef WIN32
#include <windows.h>
#else
#include <stdio.h>
#include <stdlib.h>
#endif
#include <pthread.h>
//#define WIN32
#ifdef WIN32
#define nsleep Sleep
#else
#define nsleep usleep
#endif
class CThreadLock
{
public:
CThreadLock() { pthread_mutex_init(&m_lock, NULL); }
~CThreadLock() { pthread_mutex_destroy(&m_lock); }
public:
void Lock() { pthread_mutex_lock(&m_lock); }
void UnLock() { pthread_mutex_unlock(&m_lock); }
private:
pthread_mutex_t m_lock;
};
#endif
#ifndef _UDP_NET_SHARE_H__
#define _UDP_NET_SHARE_H__
#include <vector>
#include <iostream>
#include <map>
#ifdef WIN32
#include <WinSock2.h>
#else
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <stdint.h>
#include <pthread.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <syslog.h>
#include <dirent.h>
#include <sys/time.h>
#include <sys/socket.h>
#endif
#include "sysfun.h"
#define MAX_BUFFER 65535
#define PACKSIZE 65000
typedef struct _NetData {
int nIndex;
int nBufSize;
bool bFinish;
char buffer[PACKSIZE];
int nTotalSize;
}NetData;
class UDPNetShare
{
public:
UDPNetShare(); //實例化
~UDPNetShare();
#ifdef WIN32
bool InitWith(SOCKET sock); //初始化端口
#else
bool InitWith(int sock);
#endif
int PushData(int nSize, char* pBuf); //推送數據
bool InitIPPort(const char* strIP, int nPort); //發送端口
bool SetSleepTime(int time); //发送间隔时间
bool GetClientSleep() { return m_SleepTime; } //获取休眠时间
std::vector<std::map<int, char*>> m_arrData; //存储发不完的数据
#ifdef WIN32
SOCKET m_sock; //socket
#else
int m_sock;
#endif
sockaddr_in m_clientaddr; //發送地址
int m_SleepTime; //發送休眠時間
public:
CThreadLock m_lock;
};
#endif
#include "UDPNetShare.h"
#include "sysfun.h"
#include "sysfun.h"
using namespace std;
UDPNetShare::UDPNetShare():m_SleepTime(3)
{
}
UDPNetShare::~UDPNetShare()
{
}
#ifdef WIN32
bool UDPNetShare::InitWith(SOCKET sock)
{
m_sock = sock;
return true;
}
#else
bool UDPNetShare::InitWith(int sock)
{
m_sock = sock;
return true;
}
#endif
int UDPNetShare::PushData(int nSize, char* pBuf)
{
std::map<int, char*> mapData;
mapData.insert(std::pair<int, char*>(nSize, pBuf));
m_lock.Lock();
m_arrData.push_back(mapData);
cout << "push data-------------------------size:" << m_arrData.size() << endl;
m_lock.UnLock();
return m_arrData.size();
}
void* IdleSendDataThread(void* pArgs)
{
UDPNetShare* pShare = (UDPNetShare*)pArgs;
while (1)
{
if (pShare->m_arrData.size() > 0)
{
pShare->m_lock.Lock();
std::vector<std::map<int, char*>>::iterator iterData = pShare->m_arrData.begin();
{
std::map<int, char*>::iterator iterMap = iterData->begin();
NetData pack;
int t_nCount = iterMap->first / PACKSIZE;
int t_nMod = iterMap->first % PACKSIZE;
if (t_nMod != 0)
t_nCount += 1;
memset(pack.buffer, '\0', PACKSIZE);
pack.bFinish = false;
pack.nIndex = 0;
pack.nBufSize = 0;
pack.nTotalSize = 0;
for (int j = 1; j <= t_nCount; ++j)
{
pack.nIndex = j;
pack.nTotalSize = iterMap->first;
if (j < t_nCount)
{
pack.bFinish = false;
pack.nBufSize = PACKSIZE;
memcpy(pack.buffer, iterMap->second + PACKSIZE*(j - 1), PACKSIZE);
}
else
{
printf("finish\n");
pack.bFinish = true;
pack.nBufSize = iterMap->first - PACKSIZE*(t_nCount - 1);
memcpy(pack.buffer, iterMap->second + PACKSIZE*(j - 1), pack.nBufSize);
}
int ret = sendto(pShare->m_sock, (char*)&pack, sizeof(NetData), 0, (sockaddr*)&(pShare->m_clientaddr), sizeof(pShare->m_clientaddr));
if (ret > 0)
printf("Send %d OK To Server\n", pack.nIndex);
nsleep(pShare->GetClientSleep()*1000);
}
free(iterMap->second);
pShare->m_arrData.erase(iterData);
cout << "pop data**************************size:" << pShare->m_arrData.size() << endl;
pShare->m_lock.UnLock();
printf("finish--\n");
}
}
else
{
nsleep(1000);
}
}
}
bool UDPNetShare::InitIPPort(const char* strIP, int nPort)
{
int addrLen = sizeof(struct sockaddr_in);
cout << "socket create success" << endl;
m_clientaddr.sin_family = AF_INET;
m_clientaddr.sin_port = htons(nPort);
#ifdef WIN32
m_clientaddr.sin_addr.S_un.S_addr = inet_addr(strIP);
#else
m_clientaddr.sin_addr.s_addr = inet_addr(strIP);
#endif
//启动线程
pthread_t pid;
if (pthread_create(&pid, NULL, IdleSendDataThread, this) != 0)
{
cout << "thread send create failed" << endl;
return false;
}
else
{
pthread_detach(pid);
cout << "thread send create success" << endl;
}
return true;
}
bool UDPNetShare::SetSleepTime(int time)
{
m_SleepTime = time;
return true;
}
Makefile
CC = g++ -std=c++11
cflags = -I. #./libevent/include
INC = -L. #libevent/lib
SRCS = MultiNetUtil.cpp UDPNetShare.cpp
C_FLAGS = -lpthread #-levent_core -levent_extra -levent_openssl -levent_pthreads
# -lopencv_imgcodecs
LIBRARY = libmultinetutil.so
all:
$(CC) $(SRCS) $(C_FLAGS) -fPIC --shared -O2 -g -o $(LIBRARY) $(INC) $(cflags)
cp $(LIBRARY) ./test
cp MultiNetUtil.h ./test
cp sysfun.h ./test
clean:
rm libmultinetutil.so
测试程序:
#include "MultiNetUtil.h"
#include "sysfun.h"
#ifdef WIN32
#pragma comment(lib, "MultiNetUtil.lib")
#endif
using namespace std;
int main(void)
{
cout << "hello start" << endl;
MultiNetUtil *pShare = createNetUtil();
pShare->InitSocket(6666);
char chBuf[100] = "123456hg";
pShare->SetSleepTime(10);
for (int i = 0; i < 1; i++)
pShare->AddIpPort("127.0.0.1", 9999+i, i);
int nIndex = 0;
int nChannel = 0;
cout << "Add Data" << endl;
for (int i = 1; i < 41; i++)
{
sprintf(chBuf, "/home/long/Databases/netimg/sendimg/%d.jpg", i);
FILE * fp = fopen(chBuf, "rb");
if (fp == NULL)
{
cout << "Open file Error" << endl;
return -1;
}
int size = 0;
fseek(fp, 0, SEEK_END);
size = ftell(fp);
fseek(fp, 0, SEEK_SET);
//rewind(fp);
char * tmpBuf = (char*)malloc(size);
fread(tmpBuf, 1, size, fp);
pShare->PushData(nChannel, size, tmpBuf);
fclose(fp);
nChannel++;
if (nChannel == 1)
{
nChannel = 0;
}
nIndex++;
cout << "total number========================:" << nIndex << endl;
if(nIndex == 40)
break;
usleep(300);
if (i == 40)
i = 0;
}
cout << "Send Over" << endl;
//nsleep(100000);
cout << "hello endl" << endl;
getchar();
return 0;
}
测试程序Makefile
CC = g++ -std=c++11
cflags = -I.#./libevent/include
INC = -L. # ../libevent/lib -L ./
SRCS = test.cpp
C_FLAGS = -lpthread -lmultinetutil #-levent_core -levent_extra -levent_openssl -levent_pthreads
# -lopencv_imgcodecs
LIBRARY = test
all:
$(CC) $(SRCS) $(C_FLAGS) -O2 -g -o $(LIBRARY) $(INC) $(cflags)
#cp $(LIBRARY) /home/VideoAnalysis/Bin/
clean:
rm test
发送接受源码
https://download.csdn.net/download/chnim/10499799