忘了加上一句,我写的这个是一对多的数据传输,发送端启动的时候可以插入
多个channel,ip,port;每次需要指定channel推送数据,在相应的ip,port的就能收到数据
同理tcp的那个例子也是这样的
加QQ群一起交流学习音视频开发:476513431
文件接收端:
#include "NetUtil.h"
#ifdef USE_EVENT
using namespace evenet;
#endif
#include "TcpNetShare.h"
#include "UdpNetShare.h"
//class TcpNetShare;
//class UdpNetShare;
NetUtil* createNetUtil(TU what/*= TU_TCP*/)
{
if (what == TU_TCP)
return reinterpret_cast<NetUtil*>(new TcpNetShare());
else
return reinterpret_cast<NetUtil*>(new UdpNetShare());
}
void* createNetUtilInternal()
{
return new TcpNetShare();
}
NetUtil::NetUtil():m_bRead(false)
{
#ifdef WIN32
WSAData wsa;
WSAStartup(2, &wsa);
#endif
}
evenet::NetUtil::~NetUtil()
{
#ifdef WIN32
WSACleanup();
#endif
}
void NetUtil::SetDataCallback(OUTPUT_CALLBACK output, void* pUserData)
{
}
#ifndef _NET_UTIL_H__
#define _NET_UTIL_H__
#include <iostream>
#include <vector>
#include <map>
#include <stdio.h>
#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>
#define USE_EVENT
#define MAX_BUFFER 65535
#define PACKSIZE 65000
typedef unsigned char BYTE;
enum ErrorCode {
PortError,
IpError,
CreateError,
BindError,
CreateSuccess,
BlockError,
UnknownError
};
typedef struct _NetData {
int nIndex;
int nBufSize;
bool bFinish;
char buffer[PACKSIZE];
int nTotalSize;
}NetData;
typedef struct _RECVDATA {
int nDataSize;
int nDataIndex;
char* pBuf;
}RECVDATA;
enum TU {
TU_TCP,
TU_UDP,
TU_TOTAL
};
/************************************************************************/
/* NetUtilʹ\D3\C3\D3\DA\CD\F8\C2繲\CF\ED\B5Ĺ\A4\BE߿\E2 */
/************************************************************************/
//\B3\F5\B2\E2\BBص\F7\D3\C3\D3ڽ\D3\CA\D5\CA\FD\BE\DD
typedef void(*OUTPUT_CALLBACK)(void *pUserData, char *decOutput);
extern "C" {
void* createNetUtilInternal();
}
namespace evenet {
class NetUtil {
public:
/*
Constructor
*/
NetUtil();
/*
Destructor
*/
virtual ~NetUtil();
/*
\BFͻ\A7\B6˳\F5ʼ\BB\AFIP\BAͶ˿\DA
*/
virtual ErrorCode InitWithIPPort(const char* ip, int port) = 0;
/*
\B7\FE\CE\F1\C6\F7\B6˳\F5ʼ\BB\AFIP
*/
virtual ErrorCode InitWithPort(int port) = 0;
/*
\B7\A2\CB\CD\CA\FD\BE\DD
*/
virtual int SendData(int totalSize, char* pSendBuf) = 0;
/*
\BF\BF\BF\BF\BF\BF\BF
*/
virtual int SetMultiThread(int nNum) = 0;
/*
\C9\E8\D6ûص\F7\BB\F1ȡ\CA\FD\BEݰ\FC
ע\B2\E1\BBص\F7\BB\F1ȡ\CA\E4\B3\F6\CA\FD\BE\DD
*/
virtual void SetDataCallback(OUTPUT_CALLBACK output, void* pUserData);
/*
\C9\E8\D6ÿͻ\A7\B6\CB˯\C3\DFʱ\BC\E4
*/
virtual void SetClientSleep(int nNum = 5) = 0;
/*
\C9\E8\D6÷\FE\CE\F1\B6\CB˯\C3\DFʱ\BC\E4
*/
virtual void SetServerSleep(int nNum = 1) = 0;
public:
bool m_bRead; //\B7\FE\CE\F1\B6\CB\CAǷ\F1\B1\B8\BAý\D3\CA\D5\CA\FD\BE\DD
protected:
int m_nClientSleepTime;
int m_nServerSleepTime;
};
}
evenet::NetUtil* createNetUtil(TU what = TU_UDP);
#endif
#ifndef _TCP_NET_SHARE_H__
#define _TCP_NET_SHARE_H__
#include "NetUtil.h"
#ifdef USE_EVENT
#include <event2/util.h>
#include <event.h>
#endif
typedef struct sockaddr SA;
namespace evenet {
class TcpNetShare : public NetUtil {
public:
TcpNetShare();
virtual ~TcpNetShare();
/*
\BFͻ\A7\B6˳\F5ʼ\BB\AFIP\BAͶ˿\DA
*/
ErrorCode InitWithIPPort(const char* ip, int port);
/*
\B7\FE\CE\F1\C6\F7\B6˳\F5ʼ\BB\AFIP
*/
ErrorCode InitWithPort(int port);
/*
\B7\A2\CB\CD\CA\FD\BE\DD
*/
int SendData(int totalSize, char* pSendBuf);
/*
\BF\BF\BF\BF\BF\BF\BF
*/
virtual int SetMultiThread(int nNum);
/*
\BB\F1ȡ\CA\FD\BE\DD
*/
int GetData(int* nSize, char** pBuf);
/*
\C9\E8\D6ÿͻ\A7\B6\CB˯\C3\DFʱ\BC\E4
*/
void SetClientSleep(int nNum = 5){m_nClientSleepTime = nNum; }
/*
\C9\E8\D6÷\FE\CE\F1\B6\CB˯\C3\DFʱ\BC\E4
*/
void SetServerSleep(int nNum = 1){m_nServerSleepTime = nNum; }
private:
/*
\B3\F5ʼ\BB\AF\BFͻ\A7\B6\CB
*/
ErrorCode InitWithTCPIP(const char* ip, int port);
/*
\B3\F5ʼ\BB\AF\B7\FE\CE\F1\C6\F7\B6\CB
*/
ErrorCode InitWithTCPPort(int port);
private:
/*
ʹ\D3\C3libevent\B3\F5ʼ\BB\AFtcp\BFͻ\A7\B6\CB
*/
int TcpConnectServer(const char* serverIp, int port);
/*
ʹ\D3\C3libevent\B3\F5ʼ\BB\AFtcp\B7\FE\CE\F1\B6\CB
*/
int TcpServerInit(int port, int time);
/*
ʹ\D3\C3socket\B3\F5ʼ\BB\AFtcp\BFͻ\A7\B6\CB
*/
/*
ʹ\D3\C3socket\B3\F5ʼ\BB\AFtcp\B7\FE\CE\F1\B6\CB
*/
private:
#ifdef WIN32
SOCKET m_sock;
#else
int m_sock;
#endif
sockaddr_in m_servaddr;
private:
struct event *m_clientevrdsock; //\BFͻ\A7\B6\CB\D3\C3\D3ڶ\C1ȡsocket\CA\FD\BE\DD
struct event *m_clientevwrsock; //\BFͻ\A7\B6\CB\D3\C3\D3\DAд\C8\EBsocket\CA\FD\BE\DD
public:
struct event* GetClientRDEvent() { return m_clientevrdsock; }
struct event* GetClientWREvent() { return m_clientevwrsock; }
public:
std::vector<std::map<int, char*>> m_arrSendData;
std::vector<std::map<int, char*>> m_arrRecvData;
RECVDATA data;
int m_recvCount;
struct event_base* m_base;
std::vector<struct event*> m_arrEv;
bool m_bServerInit;
};
}
#endif // _TCP_NET_SHARE_H__
#include "TcpNetShare.h"
using namespace evenet;
using namespace std;
#pragma comment(lib, "event.lib")
#pragma comment(lib, "event_core.lib")
#pragma comment(lib, "event_extra.lib")
#pragma comment(lib, "event_openssl.lib")
TcpNetShare::TcpNetShare():m_bServerInit(false)
{
data.pBuf = (char*)malloc(1024 * 10000000);
int m_recvCount = 1;
}
/*
\BF\BF\BF\BF\BF\BF\BF
*/
int TcpNetShare::SetMultiThread(int nNum)
{
}
TcpNetShare::~TcpNetShare()
{
}
ErrorCode TcpNetShare::InitWithIPPort(const char* ip, int port)
{
return InitWithTCPIP(ip, port);
}
ErrorCode TcpNetShare::InitWithPort(int port)
{
return InitWithTCPPort(port);
}
ErrorCode TcpNetShare::InitWithTCPIP(const char* ip, int port)
{
#if 0
TcpConnectServer(ip, port);
#endif
return CreateSuccess;
}
ErrorCode TcpNetShare::InitWithTCPPort(int port)
{
#if 1
m_sock = socket(AF_INET, SOCK_STREAM, 0);
if (m_sock <= 0)
{
cout << "create tcp socket error" << endl;
return CreateError;
}
#ifdef WIN32
m_servaddr.sin_family = AF_INET;
m_servaddr.sin_port = htons(port);
m_servaddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
#else
m_servaddr.sin_family = AF_INET;
m_servaddr.sin_port = htons(port);
m_servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
#endif
if (bind(m_sock, (sockaddr*)&m_servaddr, sizeof(sockaddr)) < 0)
{
cout << "bind error " << port << endl;
return PortError;
}
listen(m_sock, 5);
#endif
#if 0
//ʹ\D3\C3libevent\A3\AC\BF\C9\D2\D4֧\B3ֶ\E0\BFͻ\A7\B6\CB
TcpServerInit(port, 10);
#endif
return CreateSuccess;
}
/*
\B7\A2\CB\CD\CA\FD\BE\DD
*/
int TcpNetShare::SendData(int totalSize, char* pSendBuf)
{
std::map<int, char*> mapData;
mapData.insert(std::pair<int, char*>(totalSize, pSendBuf));
m_arrSendData.push_back(mapData);
return 1;
}
void ReadSocketCallback(evutil_socket_t fd, short events, void* params)
{
TcpNetShare *pShare = (TcpNetShare*)params;
BYTE* buffer = new BYTE[MAX_BUFFER];
int fsize = sizeof(sockaddr);
int ret = 0, len;
len = recv(fd, (char*)buffer, MAX_BUFFER, ret);
if (len == -1)
pShare->m_recvCount = 1;
NetData *pack;
pack = (NetData*)buffer;
int iCount = pack->nIndex;
int iBufferSize = pack->nBufSize;
bool bFinish = pack->bFinish;
printf("%d--%d--%d--%d--%s\n", pShare->m_recvCount, iCount, iBufferSize, bFinish, "buffer");
if (pShare->m_recvCount == iCount)
{
memcpy(pShare->data.pBuf + PACKSIZE*(pShare->m_recvCount - 1), pack->buffer, iBufferSize);
pShare->m_recvCount += 1;
if (bFinish)
{
pShare->m_recvCount = 1;
pShare->data.nDataSize = pack->nTotalSize;
printf("finish\n");
std::map<int, char*> mapData;
char* tmpBuf = (char*)malloc(pShare->data.nDataSize);
memcpy(tmpBuf, pShare->data.pBuf, pShare->data.nDataSize);
mapData.insert(std::pair<int, char*>(pShare->data.nDataSize, tmpBuf));
pShare->m_arrRecvData.push_back(mapData);
}
}
else
{
pShare->m_recvCount = 1;
}
event_active(pShare->GetClientRDEvent(), EV_PERSIST, 0);
}
void WriteSocketCallback(evutil_socket_t fd, short events, void* params)
{
TcpNetShare *pShare = (TcpNetShare*)params;
if (pShare->m_arrSendData.size() > 0)
{
std::vector<std::map<int, char*>>::iterator iterData = pShare->m_arrSendData.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 = 0;
ret = send(fd, (char*)&pack, sizeof(NetData), ret);
if (ret > 0)
printf("Send %d OK To Server\n", pack.nIndex);
}
free(iterMap->second);
pShare->m_arrSendData.erase(iterData);
printf("finish--\n");
}
}
event_active(pShare->GetClientWREvent(), EV_PERSIST, 0);
}
/*
\B3\F5ʼ\BB\AFsocket\B2\A2\C7\D2\C1\BD\BC\B6\B7\FE\CE\F1\C6\F7
*/
int TcpNetShare::TcpConnectServer(const char* serverIp, int port)
{
#ifdef _WIN32
SOCKET sockfd;
#else
int sockfd;
#endif
int status, save_errno;
//1\A1\A2\B3\F5ʼ\BB\AF\B5\D8ַ
struct sockaddr_in servaddr;
memset(&servaddr, '\0', sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(port);
#ifdef _WIN32
servaddr.sin_addr.S_un.S_addr = inet_addr(serverIp);
#else
status = inet_aton(serverIp, &servaddr.sin_addr);
#endif
//2\A1\A2\B4\B4\BD\A8socket
sockfd = ::socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1)
return -1;
//\C1\AC\BDӷ\FE\CE\F1\C6\F7
status = ::connect(sockfd, (SA*)&servaddr, sizeof(servaddr));
if (status == -1)
{
save_errno = errno;
#ifdef _WIN32
closesocket(sockfd);
#else
::close(sockfd);
#endif
errno = save_errno;
return -1;
}
//4\C9\E8\D6÷Ƕ\C2\C8\FB\BB\B7\BE\B3
evutil_make_socket_nonblocking(sockfd);
//4\A1\A2\B4\B4\BD\A8base
struct event_base* base = event_base_new();
// \BD\D3\CAջ\BA\B3\E5\C7\F8
int nRecvBuf = 32 * 1024; //\C9\E8\D6\C3Ϊ32K
setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (const char*)&nRecvBuf, sizeof(int));
//\B7\A2\CBͻ\BA\B3\E5\C7\F8
int nSendBuf = 32 * 1024;//\C9\E8\D6\C3Ϊ32K
setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (const char*)&nSendBuf, sizeof(int));
//\CC\ED\BCӶ\C1ȡsocket\D0\C5Ϣevent
m_clientevrdsock = event_new(base, sockfd, EV_READ | EV_PERSIST, ReadSocketCallback, this);
event_add(m_clientevrdsock, NULL);
event_active(m_clientevrdsock, EV_PERSIST, 0);
//\CC\ED\BC\D3д\C8\EBsocket\D0\C5Ϣevent
m_clientevwrsock = event_new(base, sockfd, EV_READ | EV_PERSIST, WriteSocketCallback, this);
event_add(m_clientevwrsock, NULL);
event_active(m_clientevwrsock, EV_PERSIST, 0);
event_base_dispatch(base);
return 1;
}
int TcpNetShare::GetData(int* nSize, char** pBuf)
{
if (m_arrRecvData.size() > 0)
{
std::vector<std::map<int, char*>>::iterator iterData = m_arrRecvData.begin();
std::map<int, char*>::iterator iterMap = iterData->begin();
*nSize = iterMap->first;
memcpy(*pBuf, iterMap->second, iterMap->first);
return *nSize;
}
else
{
return 0;
}
}
void socket_read_cb(evutil_socket_t fd, short events, void *arg)
{
std::cout << "socket" << std::endl;
TcpNetShare* pShare = (TcpNetShare*)arg;
struct event *ev = pShare->m_arrEv.front();
BYTE* buffer = new BYTE[MAX_BUFFER];
//\B6\C1ȡ\CA\FD\BE\DD
int len = recv(fd, (char*)buffer, MAX_BUFFER, 0);
if (len <= 0)
{
std::cout << "recv error" << std::endl;
event_free(ev);
#ifdef WIN32
closesocket(fd);
#else
close(fd);
#endif
}
NetData *pack;
pack = (NetData*)buffer;
int iCount = pack->nIndex;
int iBufferSize = pack->nBufSize;
bool bFinish = pack->bFinish;
printf("%d--%d--%d--%d--%s\n", pShare->m_recvCount, iCount, iBufferSize, bFinish, "buffer");
if (pShare->m_recvCount == iCount)
{
memcpy(pShare->data.pBuf + PACKSIZE*(pShare->m_recvCount - 1), pack->buffer, iBufferSize);
pShare->m_recvCount += 1;
if (bFinish)
{
pShare->m_recvCount = 1;
pShare->data.nDataSize = pack->nTotalSize;
char* pTmp = (char*)malloc(pShare->data.nDataSize);
memcpy(pTmp, pShare->data.pBuf, pShare->data.nDataSize);
std::map<int, char*> mapData;
mapData.insert(std::pair<int, char*>(pShare->data.nDataSize, pTmp));
pShare->m_arrRecvData.push_back(mapData);
printf("finish\n");
}
}
else
{
pShare->m_recvCount = 1;
}
}
//\B4\B4\BD\A8\BFͻ\A7\C1\B4\BD\D3\C7\EB\C7\F3\BBص\F7
void AcceptCallback(evutil_socket_t fd, short events, void* params)
{
printf("accept_cb\n");
//5\A1\A2\BD\D3\CAտͻ\A7\B6\CB\C1\AC\BD\D3
evutil_socket_t sockfd;
struct sockaddr_in clientaddr;
socklen_t len = sizeof(clientaddr);
sockfd = ::accept(fd, (struct sockaddr*)&clientaddr, &len);
//\C9\E8\D6ò\BB\B6\C2\C8\FB
evutil_make_socket_nonblocking(sockfd);
printf("%s_%d_%d\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port), sockfd);
TcpNetShare* pShare = (TcpNetShare*)params;
//\B5\E3\B6Ե\E3\D4\DDʱ\B2\BB\BF\BC\C2Ƿ\FE\CE\F1\C6\F7\C0\E0\D0\CD
if(pShare->m_arrEv.size() > 0)
return;
//\B4\B4\BD\A8\B6\AF̬\BDṹ\CC\E5
struct event* ev = event_new(NULL, -1, 0, NULL, NULL);
pShare->m_arrEv.push_back(ev);
//6\A1\A2\BDṹ\CC\E5\C9\E8\D6ûص\F7\BA\AF\CA\FD
event_assign(ev, pShare->m_base, sockfd, EV_READ | EV_PERSIST, socket_read_cb, (void*)pShare);
event_add(ev, NULL);
}
/*
\B7\FE\CE\F1\C6\F7\B3\F5ʼ\BB\AF
*/
int TcpNetShare::TcpServerInit(int port, int time)
{
printf("server init\n");
int errno_save;
evutil_socket_t listener;
//1\A1\A2\B4\B4\BD\A8socket
listener = ::socket(AF_INET, SOCK_STREAM, 0);
if (listener == -1)
return -1;
//2\A1\A2\C9\E8\D6\C3\D4\CA\D0\ED\B6\E0\B4ΰ\F3\B6\A8
evutil_make_listen_socket_reuseable(listener);
struct sockaddr_in sinaddr;
sinaddr.sin_family = AF_INET;
sinaddr.sin_port = htons(port);
#ifdef _WIN32
sinaddr.sin_addr.S_un.S_addr = 0;
#else
sinaddr.sin_addr.s_addr = 0;
#endif
if (::bind(listener, (SA*)&sinaddr, sizeof(sinaddr)) < 0)
{
errno_save = errno;
evutil_closesocket(listener);
errno = errno_save;
return -1;
}
if (::listen(listener, time) < 0)
{
errno_save = errno;
evutil_closesocket(listener);
errno = errno_save;
return -1;
}
//\C9\E8\D6÷\C7\D7\E8\C8\FB״̬
evutil_make_socket_nonblocking(listener);
//3\A1\A2\B4\B4\BD\A8base
m_base = event_base_new();
//4\A1\A2\CC\ED\BCӿͻ\A7\C1\AC\BD\D3\C7\EB\C7\F3ʱ\BC\E4
struct event* evlistener = event_new(m_base, listener, EV_READ | EV_PERSIST, AcceptCallback, this);
event_add(evlistener, NULL);
event_base_dispatch(m_base);
return listener;
}
#ifndef _EVE_NET_SHARE_H__
#define _EVE_NET_SHARE_H__
#include "NetUtil.h"
namespace evenet
{
class UdpNetShare : public NetUtil
{
public:
//\B9\B9\D4캯\CA\FD
UdpNetShare();
virtual ~UdpNetShare();
//\BFͻ\A7\B6˳\F5ʼ\BB\AFIP\BAͶ˿\DA
ErrorCode InitWithIPPort(const char* ip, int port);
//\B7\FE\CE\F1\C6\F7\B6˳\F5ʼ\BB\AFIP
ErrorCode InitWithPort(int port);
//\B7\A2\CB\CD\CA\FD\BE\DD
int SendData(int totalSize, char* pSendBuf);
//ע\B2\E1\BBص\F7\BB\F1ȡ\CA\E4\B3\F6\CA\FD\BE\DD
void SetDataCallback(OUTPUT_CALLBACK output, void* pUserData);
/*
\C9\E8\D6÷\C7\D7\E8\C8\FB\B3\ACʱ
*/
void SetNoBlocking(int timesec, int timemsec);
/*
\C9\E8\D6ÿͻ\A7\B6\CB˯\C3\DFʱ\BC\E4
*/
void SetClientSleep(int nNum = 5);
/*
\BF\BF\BF\BF\BF\BF\BF
*/
virtual int SetMultiThread(int nNum);
/*
\C9\E8\D6÷\FE\CE\F1\B6\CB˯\C3\DFʱ\BC\E4
*/
void SetServerSleep(int nNum = 1);
public:
int GetServerSleep();
int GetClientSleep();
private:
/*
\BFͻ\A7\B6˳\F5ʼ\BB\AF
*/
ErrorCode InitWithUDPIP(const char* ip, int port);
/*
\B7\FE\CE\F1\C6\F7\B6˳\F5ʼ\BB\AF
*/
ErrorCode InitWithUDPPort(int port);
int m_nClientSleepTime;
int m_nServerSleepTime;
protected:
/*
\B8\A8\D6\FA\CF߳\CC\D3\C3\D3ڼ\EC\B2\E2\CA\FD\BEݴ\AB\CA\E4\CAǷ\F1\B4\AB\CA\E4\D5\FD\B3\A3
*/
public:
std::vector<std::map<int, char*>> m_arrData; //\B4洢\B7\A2\B2\BB\CD\EA\B5\C4\CA\FD\BE\DD
private:
TU m_type;
public:
struct sockaddr_in m_clientaddr;//\BFͻ\A7\B6˵\D8ַ
struct sockaddr_in m_servaddr; //\B7\FE\CE\F1\C6\F7\B5\D8ַ
private:
int m_port;
struct timeval m_timeout;
bool m_IsBlock; //\CAǷ\F1\D7\E8\C8\FBģʽ
bool m_IsSend; //\CAǷ\F1\D2Ѵ\B4\BD\A8\B7\A2\CB\CD\CF߳\CC
int m_RecvThread; //\BF\BF\BF\BF
public:
OUTPUT_CALLBACK m_recvcall; //\BD\D3\CA\D5\CA\FD\BEݵĻص\F7\BA\AF\CA\FD
void * m_pUserData; //\D3û\A7\CA\FD\BE\DD
#ifdef WIN32
SOCKET m_sock; //\CC\D3\D7\D6
#else
int m_sock;
#endif
};
}
#endif
#include "UdpNetShare.h"
#include <map>
#include <pthread.h>
#ifdef USE_EVENT
using namespace evenet;
#endif
using namespace std;
//#define GTEST
#ifdef GTEST
/*\D2\FD\C8\EB\B9ȸ\E8\B2\E2\CA\D4*/
#include <gtest/gtest.h>
#pragma comment(lib, "gtest_main.lib")
#pragma comment(lib, "gtest.lib")
#pragma comment(lib, "gmock_main.lib")
#pragma comment(lib, "gmock.lib")
#endif
#ifdef WIN32
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "pthreadVC2.lib")
#endif
//\C9\E8\D6÷\C7\D7\E8\C8\FB
//static void setnonblocking(int sockfd) {
// int flag = fcntl(sockfd, F_GETFL, 0);
// if (flag < 0) {
// Perror("fcntl F_GETFL fail");
// return;
// }
// if (fcntl(sockfd, F_SETFL, flag | O_NONBLOCK) < 0) {
// Perror("fcntl F_SETFL fail");
// }
//}
int UdpNetShare::SendData(int totalSize, char* pSendBuf)
{
std::map<int, char*> mapData;
mapData.insert(std::pair<int, char*>(totalSize, pSendBuf));
m_arrData.push_back(mapData);
return m_arrData.size();
}
/*
\BF\BF\BF\BF\BF\BF\BF
*/
int UdpNetShare::SetMultiThread(int nNum)
{
m_RecvThread = nNum;
}
UdpNetShare::UdpNetShare():m_IsBlock(true),m_nClientSleepTime(5),m_nServerSleepTime(1),m_RecvThread(1)
{
//m_type = what;
}
UdpNetShare::~UdpNetShare()
{
}
ErrorCode UdpNetShare::InitWithIPPort(const char* ip, int port)
{
return InitWithUDPIP(ip, port);
}
ErrorCode UdpNetShare::InitWithPort(int port)
{
return InitWithUDPPort(port);
}
void* IdleRecvDataThread(void* pArgs)
{
UdpNetShare* pShare = (UdpNetShare*)pArgs;
RECVDATA data;
data.pBuf = (char*)malloc(1024 * 10000000);
int m_recvCount = 1;
pShare->m_bRead = true;
while (1)
{
if (pShare->m_bRead)
{
cout << "get data" << endl;
BYTE* buffer = new BYTE[MAX_BUFFER];
#ifdef WIN32
int fsize = sizeof(sockaddr);
int len = recvfrom(pShare->m_sock, (char*)buffer, MAX_BUFFER, 0, (sockaddr*)&(pShare->m_servaddr), &fsize);
#else
socklen_t fsize = sizeof(sockaddr);
int len = recvfrom(pShare->m_sock, (char*)buffer, MAX_BUFFER, 0, (sockaddr*)&(pShare->m_servaddr), &fsize);
#endif
if (len == -1)
m_recvCount = 1;
NetData *pack;
pack = (NetData*)buffer;
int iCount = pack->nIndex;
int iBufferSize = pack->nBufSize;
bool bFinish = pack->bFinish;
printf("%d--%d--%d--%d--%s\n", m_recvCount, iCount, iBufferSize, bFinish, "buffer");
if (m_recvCount == iCount)
{
memcpy(data.pBuf + PACKSIZE*(m_recvCount - 1), pack->buffer, iBufferSize);
m_recvCount += 1;
if (bFinish)
{
m_recvCount = 1;
data.nDataSize = pack->nTotalSize;
printf("finish\n");
pShare->m_recvcall(pShare->m_pUserData, (char*)&data);
}
}
else
{
m_recvCount = 1;
}
#ifdef WIN32
Sleep(pShare->GetServerSleep());
#else
usleep(pShare->GetServerSleep()*10);
#endif
delete buffer;
}
else
{
char chRead[20];
#ifdef WIN32
int fsize = sizeof(sockaddr);
int ret = recvfrom(pShare->m_sock, chRead, 20, 0, (sockaddr*)&(pShare->m_servaddr), &fsize);
#else
socklen_t fsize = sizeof(sockaddr);
int ret = recvfrom(pShare->m_sock, chRead, 20, 0, (sockaddr*)&(pShare->m_servaddr), &fsize);
#endif
cout << chRead << endl;
if (ret >= 0)
{
if (strstr(chRead, "IsRead") != NULL)
{
sprintf(chRead, "%s", "OK");
ret = sendto(pShare->m_sock, (char*)&chRead, 20, 0, (sockaddr*)&(pShare->m_servaddr), sizeof(pShare->m_servaddr));
if (ret >= 0)
{
pShare->m_bRead = true;
cout << chRead << endl;
}
}
}
}
}
}
void* IdleSendDataThread(void* pArgs)
{
UdpNetShare* pShare = (UdpNetShare*)pArgs;
pShare->m_bRead = true;
while(1)
{
#ifdef WIN32
Sleep(100);
#else
usleep(100000);
#endif
if (pShare->m_arrData.size() > 0)
{
if (pShare->m_bRead)
{
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);
#ifdef WIN32
Sleep(pShare->GetClientSleep());
#else
usleep(pShare->GetClientSleep()*1000);
#endif
}
free(iterMap->second);
pShare->m_arrData.erase(iterData);
printf("finish--\n");
}
}
else
{
char chRead[20];
sprintf(chRead, "%s", "IsRead");
#ifdef WIN32
int len = sizeof(sockaddr);
int ret = sendto(pShare->m_sock, (char*)&chRead, sizeof(chRead), 0, (sockaddr*)&(pShare->m_clientaddr), sizeof(pShare->m_clientaddr));
#else
socklen_t len = sizeof(sockaddr);
int ret = sendto(pShare->m_sock, (char*)&chRead, sizeof(chRead), 0, (sockaddr*)&(pShare->m_clientaddr), sizeof(pShare->m_clientaddr));
#endif
if (ret >= 0)
{
#ifdef WIN32
Sleep(5);
#else
usleep(50000);
#endif
int ret = recvfrom(pShare->m_sock, chRead, sizeof(chRead), 0, (sockaddr*)&(pShare->m_clientaddr), &len);
if (ret >= 0)
{
if (strstr(chRead, "OK") != NULL)
pShare->m_bRead = true;
}
}
}
}
}
}
void UdpNetShare::SetDataCallback(OUTPUT_CALLBACK output, void* pUserData)
{
cout << "create thread recv" << endl;
m_recvcall = output;
m_pUserData = pUserData;
pthread_t pid;
for(int i = 0; i < m_RecvThread; i++)
{
if (pthread_create(&pid, NULL, IdleRecvDataThread, this) != 0)
{
cout << "thread recv create failed" << endl;
}
else
{
pthread_detach(pid);
cout << "thread recv create success" << endl;
}
}
}
void UdpNetShare::SetNoBlocking(int timesec, int timemsec)
{
m_timeout.tv_sec = timesec;
m_timeout.tv_usec = timemsec;
m_IsBlock = false;
}
/*
\C9\E8\D6ÿͻ\A7\B6\CB˯\C3\DFʱ\BC\E4
*/
void UdpNetShare::SetClientSleep(int nNum /*= 5*/)
{
m_nClientSleepTime = nNum;
}
/*
\C9\E8\D6÷\FE\CE\F1\B6\CB˯\C3\DFʱ\BC\E4
*/
void UdpNetShare::SetServerSleep(int nNum /*= 1*/)
{
m_nServerSleepTime = nNum;
}
int evenet::UdpNetShare::GetServerSleep()
{
return m_nServerSleepTime;
}
int UdpNetShare::GetClientSleep()
{
return m_nClientSleepTime;
}
/*
\B3\F5ʼ\BB\AFtcp socket
*/
ErrorCode UdpNetShare::InitWithUDPIP(const char* ip, int port)
{
int addrLen = sizeof(struct sockaddr_in);
if ((m_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
cout << "socket create error" << endl;
return CreateError;
}
cout << "socket create success" << endl;
#ifdef WIN32
m_clientaddr.sin_family = AF_INET;
m_clientaddr.sin_port = htons(port);
m_clientaddr.sin_addr.S_un.S_addr = inet_addr(ip);
#else
m_clientaddr.sin_family = AF_INET;
m_clientaddr.sin_port = htons(port);
m_clientaddr.sin_addr.s_addr = inet_addr(ip);
#endif
//\C6\F4\B6\AF\CF߳\CC
pthread_t pid;
if (pthread_create(&pid, NULL, IdleSendDataThread, this) != 0)
{
cout << "thread send create failed" << endl;
}
else
{
pthread_detach(pid);
cout << "thread send create success" << endl;
}
return CreateSuccess;
}
ErrorCode UdpNetShare::InitWithUDPPort(int port)
{
m_sock = socket(AF_INET, SOCK_DGRAM, 0);
if (m_sock == -1) {
cout << "create socket error" << endl;
return CreateError;
}
if (!m_IsBlock)
{
if (setsockopt(m_sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&m_timeout, sizeof(m_timeout)) == -1)
{
return BlockError;
}
}
#ifdef WIN32
m_servaddr.sin_family = AF_INET;
m_servaddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
m_servaddr.sin_port = htons(port);
#else
m_servaddr.sin_family = AF_INET;
m_servaddr.sin_addr.s_addr = htonl(INADDR_ANY);//inet_addr("127.0.0.1");
m_servaddr.sin_port = htons(port);
#endif
if (bind(m_sock, (sockaddr*)&m_servaddr, sizeof(m_servaddr)) == -1)
{
cout << "bind error:" << port << endl;
return BindError;
}
return CreateSuccess;
}
Makefile文件:
CC = g++ -std=c++11
cflags = -I./libevent/include
INC = -L libevent/lib
SRCS = NetUtil.cpp TcpNetShare.cpp UdpNetShare.cpp
C_FLAGS = -lpthread -levent_core -levent_extra -levent_openssl -levent_pthreads
# -lopencv_imgcodecs
LIBRARY = libnetutil.so
all:
$(CC) $(SRCS) $(C_FLAGS) -fPIC --shared -O2 -g -o $(LIBRARY) $(INC) $(cflags)
cp $(LIBRARY) ./test
cp NetUtil.h ./test
clean:
rm libnetutil.so
测试程序:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include "NetUtil.h"
using namespace std;
using namespace evenet;
int g_nIndex = 0;
void outData(void* pUserData, char* pBuf)
{
//FILE *fp = (FILE*)pUserData;
char chBuf[20];
sprintf(chBuf, "./jpg/img%d.jpg", g_nIndex);
FILE *fp = fopen(chBuf, "wb");
RECVDATA* pData = (RECVDATA*)pBuf;
fseek(fp, 0, SEEK_END);
if (pData->nDataSize > 1024 * 1024 * 500)
{
int nLoop = pData->nDataSize / (1024 * 1024 * 500);
int args = pData->nDataSize % (1024 * 1024 * 500);
if (args != 0)
nLoop++;
for (int i = 0; i < nLoop; i++)
{
if (i == nLoop - 1)
{
fwrite(pData->pBuf + i*(1024 * 1024 * 500), 1, pData->nDataSize-(1024 * 1024 * 500)*i, fp);
fflush(fp);
fseek(fp, 0, SEEK_END);
printf("end\n");
}
else
{
fwrite(pData->pBuf + i*(1024 * 1024 * 500), 1, 1024 * 1024 * 500, fp);
fflush(fp);
fseek(fp, 0, SEEK_END);
printf("write %d\n", i);
}
}
}
else
{
fwrite(pData->pBuf, 1, pData->nDataSize, fp);
}
printf("hello\n");
//free(pData->pBuf);
fclose(fp);
fp == NULL;
g_nIndex++;
//printf("%s\n", pBuf);
}
int main(void)
{
cout << "test net" << endl;
NetUtil *pUtil = createNetUtil();
if(pUtil != NULL)
cout << "not endl" << endl;
else
{
cout << "create failed" << endl;
return -1;
}
//pUtil->SetMultiThread(10);
pUtil->InitWithPort(9999);
FILE *fp = fopen("z.zip", "wb");
if(fp == NULL)
return -1;
pUtil->SetServerSleep(1);
pUtil->SetDataCallback(outData, (void*)fp);
cout << "endl" << endl;
sleep(1000);
getchar();
return 0;
}
测试文件Makefile
CC = g++ -std=c++11
cflags = -I./libevent/include
INC = -L ../libevent/lib -L ./
SRCS = testnet.cpp
C_FLAGS = -lpthread -lnetutil -levent_core -levent_extra -levent_openssl -levent_pthreads
# -lopencv_imgcodecs
LIBRARY = testnet
all:
$(CC) $(SRCS) $(C_FLAGS) -O2 -g -o $(LIBRARY) $(INC) $(cflags)
#cp $(LIBRARY) /home/VideoAnalysis/Bin/
clean:
rm testnet
发送接受源码
https://download.csdn.net/download/chnim/10499799