UDP批量文件传输服务端接收端实现(二)接收端

忘了加上一句,我写的这个是一对多的数据传输,发送端启动的时候可以插入

多个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
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Python 本身不会改变服务端接收客户端信息的方式或机制。Python 作为一种编程语言,可以用于编写服务器端的应用程序,同时也可以编写客户端的应用程序。在服务器端,Python 通常使用网络编程库(如 Socket、Twisted、Tornado 等)来监听客户端的连接请求,并接收客户端发送的数据。Python 本身并不会改变服务器端接收客户端信息的方式,而是通过网络编程库提供的接口来实现相应的功能。因此,Python 可以作为一种非常灵活和强大的工具来开发各种类型的网络应用程序。 ### 回答2: Python的socket模块提供了一种实现网络通信的方式,可以在客户端和服务端之间进行信息的传输。通常情况下,客户端发送请求并等待服务端的响应,服务端接收请求,处理请求并发送响应给客户端。 在这个过程中,Python作为一种脚本语言,可以被用作客户端或者服务端的编程语言。但是无论是客户端还是服务端,Python都是通过socket进行通信,它本身并不会改变服务端接收客户端信息的方式。 具体来说,当客户端发送信息给服务端时,Python作为客户端的一部分,使用socket发送请求信息给服务端服务端使用Python的socket模块监听请求,并接收客户端发送过来的信息。服务端可以通过读取socket对象中的数据,获得客户端发送的信息。 当服务端接收到客户端的信息后,可以对信息进行处理,并根据客户端的请求作出相应的响应。服务端可以使用Python的socket模块发送响应信息给客户端,响应信息会通过socket对象发送到客户端。 总结来说,Python作为一种编程语言可以用于客户端和服务端的开发,但它本身并不会直接改变服务端接收客户端信息的方式。而是通过socket模块提供的函数和方法,实现客户端和服务端之间的通信和信息的传输。 ### 回答3: Python 是一种非常流行的编程语言,广泛用于网络编程。Python 可以作为客户端或服务端使用,具有很强的网络传输能力。在客户端向服务端发送信息时,Python 提供了许多方法和库,如 socket 模块,可以通过建立 TCP 或 UDP 连接与服务端进行通信。 Python 在客户端发送请求时并不会直接改变服务端接收的信息。当客户端发送请求到服务端时,请求会被服务端接收并进行处理。服务端可以根据收到的请求进行相应的操作,并将处理结果返回给客户端。Python 提供了丰富的网络编程工具,可以方便地与服务端进行通信。 在客户端发送信息时,Python 可以使用 socket 模块中的方法来建立网络连接,并根据需要发送具体的信息给服务端服务端接收到客户端发送的信息后,可以使用 Python 脚本进行解析和处理。Python 的网络编程库提供了很多功能,如建立连接、发送请求、接收响应、处理数据等。 服务端可以根据客户端发送的不同请求进行不同的处理,并将处理结果发送给客户端。Python 提供了丰富的网络编程库和框架,如 Flask、Django 等,可以用于构建高效可靠的服务端应用程序。 因此,Python 在客户端发送信息时,并不会直接改变服务端接收的信息。客户端和服务端通信的过程中,Python 提供了丰富的网络编程工具和库,可以方便地进行通信,实现客户端和服务端之间的信息传输和处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

telllong

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值