TCP批量文件传输服务端与客户端(一)----服务端发送端

写的有点烂,还有点问题想让大家帮忙看看

服务器端:

这是一个客户端管理类,就是服务器端,仅仅可以发送文件,头文件

/*
	MultiNetUtil.h create by long
	
	MultiNetUtil interface
*/

#ifndef _MULTI_NET_UTIL_H__
#define _MULTI_NET_UTIL_H__


#include <iostream>
#include <vector>
#include <map>
#include "sysfun.h"

#define MAX_BUFFER 65535
#define PACKSIZE 65000

#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;
class TCPNetShare;

typedef struct _CIPInfo {
	std::string strIP;
	int nPort;
	int nChannel;
	_CIPInfo()
	{
		strIP = "";
		nPort = 5000;
		nChannel = 0;
	}
}CIPPort;

/*
Server ----->client
*/
// size 
typedef struct _NetData {
	int nIndex;
	int nBufSize;
	bool bFinish;
	char buffer[PACKSIZE];
	int nTotalSize;
}NetData;

typedef struct  _DataInfo{
	int nChannel;
	char* pBuf;
	int nSize;
}DataInfo;

//�ͻ����׽��ֺͿͻ��˶�Ӧ�����·
typedef struct _TCPCleint
{
#ifdef WIN32
	SOCKET sock;
#else
	int sock;
#endif
	int nChannel;
}TCPClient;

//�˿ںź�ip��ַ��Ӧ����һ·���
typedef struct _TCPChannel
{
	std::string strIP;	//�ͻ���IP
	int nPort;		//�ͻ��˶˿�
	int nChannel;	//�ͻ���ȡ��һ·��Ƶ
}TCPChannel;

#ifdef WIN32
class OUT_EX_CLASS MultiNetUtil
#else
class MultiNetUtil
#endif
{
public:
	//���뱾�ذ


/*
	MultiNetUtil.h create by long
	
	MultiNetUtil source
*/

#include "MultiNetUtil.h"
#include "UDPNetShare.h"
#include <pthread.h>
#include "TCPNetShare.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
}

//���һ·���ն�
int MultiNetUtil::InsertChannel(int nChannel, int nPort, string strIP)
{
	TCPChannel *pChannel = new TCPChannel;
	std::vector<TCPChannel*>::iterator iterChannel = m_arrChannelInfo.begin();
	for (; iterChannel != m_arrChannelInfo.end(); ++iterChannel)
	{
		if ((*iterChannel)->nChannel == nChannel)
		{
			//�ظ�·
			printf("%d is repeadted\n", nChannel);
			return -1;
		}
		if ((*iterChannel)->nPort == nPort && strIP == (*iterChannel)->strIP)
		{
			printf("port:%d,address:%s is repeated\n", nPort, strIP.c_str());
			return -1;
		}
	}

	pChannel->nChannel = nChannel;
	pChannel->nPort = nPort;
	pChannel->strIP = strIP;
	printf("channel:%d--port:%d--address:%s insert success\n", nChannel, pChannel->nPort, pChannel->strIP.c_str());
	m_arrChannelInfo.push_back(pChannel);
	return m_arrChannelInfo.size();
}

//ɾ��ָ�����ܶ�
int MultiNetUtil::DeleteChannel(int nChannel)
{
	std::vector<TCPChannel*>::iterator iterChannel = m_arrChannelInfo.begin();
	for (; iterChannel != m_arrChannelInfo.end(); ++iterChannel)
	{
		if ((*iterChannel)->nChannel == nChannel)
		{
			m_arrChannelInfo.erase(iterChannel);
			std::map<int, TCPNetShare*>::iterator iterTCPUtil = m_mapTCPNetUtil.begin();
			for (int i = 0; iterTCPUtil != m_mapTCPNetUtil.end(); ++iterTCPUtil,i++)
			{
				if (iterTCPUtil->first == (*iterChannel)->nChannel)
				{
					printf("channel:%d--port:%d--address:%s delete success\n", nChannel, (*iterChannel)->nPort, (*iterChannel)->strIP.c_str());
					iterTCPUtil->second->Stop();
					m_mapTCPNetUtil.erase(i);
					return m_arrChannelInfo.size();
				}
			}
		}
	}
	printf("channel:%d delete failed\n", nChannel);
	return m_arrChannelInfo.size();
}

//����IP�Ͷ˿�ɾ��ָ�����ն�
int MultiNetUtil::DeleteChannel(int nPort, string strIP)
{
	return m_arrChannelInfo.size();
}

bool MultiNetUtil::HasChannel(int nChannel)
{
	#if 0
	cout << "channel size: " << m_mapTCPNetUtil.size() << endl;
	std::map<int, TCPNetShare*>::iterator iterObj = m_mapTCPNetUtil.find(nChannel);
	if(iterObj != m_mapTCPNetUtil.end())
		return true;
#endif
	
	std::vector<TCPChannel*>::iterator iterObj = m_arrChannelInfo.begin();
	for(; iterObj != m_arrChannelInfo.end(); iterObj++)
	{
		if((*iterObj)->nChannel == nChannel)
			return true;
	}
	return false;
}

void* IdleRoundThread(void* pArgs)
{
	MultiNetUtil* pUtil = (MultiNetUtil*)pArgs;
	if (pUtil != NULL)
	{
		while (true)
		{
			if (pUtil->m_arrData.size() > 0)
			{
				pUtil->m_RoundLock.Lock();
				//cout << "Remain Data:" << pUtil->m_arrData.size() << endl;
				std::vector<DataInfo*>::iterator iterInfo = pUtil->m_arrData.begin();
				std::map<int, TCPNetShare*>::iterator iterObj = pUtil->m_mapTCPNetUtil.find((*iterInfo)->nChannel);
				//if(pUtil->m_mapTCPNetUtil.size() > 0)
				//{
				//	cout << "channel info:" << iterObj->first << "channel data:" << (*iterInfo)->nChannel << endl;
				//}
				if (iterObj != pUtil->m_mapTCPNetUtil.end())
				{
					iterObj->second->PushData((*iterInfo)->nSize, (*iterInfo)->pBuf);
					cout << "channel info:" << iterObj->first << "channel data:" << (*iterInfo)->nChannel << endl;
					cout << "channel:" << (*iterInfo)->nChannel << "data size:" << pUtil->m_arrData.size() << endl;
					pUtil->m_arrData.erase(iterInfo);
				}
				pUtil->m_RoundLock.UnLock();
			}
			else
			{
				nsleep(10);
				//cout << "pic empty" << endl;
			}
		}
	}
	return NULL;
}

//���ܿͻ�������
void* IdleAcceptThread(void* pArgs)
{
	MultiNetUtil* pUtil = (MultiNetUtil*)pArgs;
	if (pUtil != NULL)
	{
		while (true)
		{
			TCPClient *pClient = new TCPClient;
			sockaddr_in cliaddr;

#ifdef WIN32
			int addrlen = sizeof(cliaddr);
            		SOCKET newfd = accept(pUtil->m_sock,(struct sockaddr *)&cliaddr,&addrlen);//�����µ��׽���)
#else
			socklen_t addrlen = sizeof(cliaddr);
			int newfd = accept(pUtil->m_sock,(struct sockaddr *)&cliaddr,&addrlen);//�����µ��׽���)
			cout << "can use ?" << endl;
#endif

#ifdef WIN32
			if(newfd != INVALID_SOCKET)
#else
			if(newfd > 0)
#endif
			{
				int bflag = 0;
				/*����IP��port��ȡ��������һ·���*/
				std::vector<TCPChannel*>::iterator iterChannelInfo = pUtil->m_arrChannelInfo.begin();
				for (; iterChannelInfo != pUtil->m_arrChannelInfo.end(); ++iterChannelInfo)
				{
					string stmp = inet_ntoa(cliaddr.sin_addr);
					int nPort = cliaddr.sin_port;

					cout << "port:" << nPort << "ip:" <<  stmp.c_str() << "--connect can use? 1" << endl;
					cout << "port:" << (*iterChannelInfo)->nPort << "ip:" <<  (*iterChannelInfo)->strIP.c_str() << "--can use?  2" << endl;

					//error - tcp client bind port but cannot effient, system select a random port to server 
					
					//error -- port rand ,so we can't defferentiate channel by port
					//if ((*iterChannelInfo)->nPort == nPort && stmp == (*iterChannelInfo)->strIP)
					if(stmp == (*iterChannelInfo)->strIP)
					{
						pClient->sock = newfd;
						pClient->nChannel = (*iterChannelInfo)->nChannel;
						TCPNetShare *pShare = new TCPNetShare(pClient);
						pShare->SetSleepTime(pUtil->GetSleepTime());
						pShare->Start();
						pUtil->m_mapTCPNetUtil[pClient->nChannel] = pShare;
						cout << "port:" << nPort << "ip:" <<  stmp.c_str() << "connect success" << endl;
						cout << "menber size:" << pUtil->m_mapTCPNetUtil.size() << endl;
						bflag = 1;
						break;
						//pUtil->m_arrClient.push_back(pClient);
					}
				}
				if(bflag == 0)
					cout << "connect suceess but cannot send data" << endl;
			}
			else
			{
				nsleep(10);
			}
		}
	}
	return NULL;
}

MultiNetUtil* createNetUtil()
{
	return new MultiNetUtil();
}

bool MultiNetUtil::InitSocket(int nPort)
{
	m_sock = socket(AF_INET, SOCK_STREAM, 0);
#ifdef WIN32
	if (m_sock == INVALID_SOCKET)
#else
	if(m_sock <= 0)
#endif
	{
		cout << "create error " << endl;
		return false;
	}
		
#ifdef WIN32
	m_servaddr.sin_family = AF_INET;
	m_servaddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	m_servaddr.sin_port = htons(nPort);
#else
	m_servaddr.sin_family = AF_INET;
	m_servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	m_servaddr.sin_port = htons(nPort);
#endif
	if (bind(m_sock, (sockaddr*)&m_servaddr, sizeof(sockaddr)) < 0)
	{
		cout << "error bind" << endl;
		return false;
	}
	
	 //����
	listen(m_sock,10);
	
	//accept thread
	pthread_t pidt;
	if (pthread_create(&pidt, NULL, IdleAcceptThread, this) != 0)
	{
		cout << "thread accept create failed" << endl;
		return false;
	}
	else
	{
		pthread_detach(pidt);
		cout << "thread accept create success" << endl;
	}

	//��������ѭ���߳�
	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)
{
	m_RoundLock.Lock();
	DataInfo * pData = new DataInfo;
	pData->nChannel = nChannel;
	pData->nSize = nTotalSize;
	pData->pBuf = pBuf;
	m_arrData.push_back(pData);
	cout << "channel: " << nChannel << "---" << "datasize: " << nTotalSize << "--Insert Success" << endl; 
	m_RoundLock.UnLock();
	return m_arrData.size();
}
/*
	TCPNetShare.h create by long
		
	TCP Server Interface

	接受客户端连接,并且将数据发送给每个客户端
	connect
	Server<----------------------------------------------Client

	data
	Server-sock------------------------------------------>Client
*/

#ifndef _TCP_NET_SHARE_H__
#define _TCP_NET_SHARE_H__

#include <vector>
#include <string>
#include <iostream>
#include "sysfun.h"

#include "MultiNetUtil.h"

using namespace std;

#if 0
#define PACKSIZE 10000000

//数据格式存储
typedef struct _NetData {
	int nIndex;
	int nBufSize;
	bool bFinish;
	char *buffer;
	int nTotalSize;
}NetData;
#endif

class TCPNetShare
{
public:
	TCPNetShare(TCPClient* client);
	~TCPNetShare();
	
public:
	int PushData(int nSize, char* pBuf);
	int PushNetData(int nSize, char* pBuf);
	bool SetSleepTime(int time);					//发送间隔时间
	int GetClientSleep() { return m_SleepTime; }   //获取休眠时间
	void Start() { m_bRuning = true; }
	void Stop() { m_bRuning = false; }
	bool GetStatus() { return m_bRuning; }

public:
	TCPClient * m_pClient;
	std::vector<std::map<int, char*>> m_arrData;	//存储发不完的数据
	std::vector<NetData> m_arrSendData;		//存储发送不玩的数据
	CThreadLock m_lock;

private:
	bool	m_bRuning;								//是否正在运行
	int m_SleepTime;								//發送休眠時間
};

#endif

#include "TCPNetShare.h"
#include "MultiNetUtil.h"
#include <pthread.h>
#include "sysfun.h"

#define BEGIN_NUM 19900711  
#define DATA_NUM  20160113  
#define END_NUM   11700991  
#define BLOCK_DATA_SIZE (10 * 1024)  
#define FILE_HEAD  4  
#define BLOCK_HEAD 4  

int TCPNetShare::PushNetData(int nSize, char* pBuf)			//发送结构数据
{
#if 0
	NetData tmpData;
	tmpData.nSize = nSize;
	tmpData.buffer = pBuf;
	m_lock.Lock();
	m_arrSendData.push_back(tmpData);
	cout << "tcp push data-------------------------size:" << m_arrData.size() << endl;
	m_lock.UnLock();
#endif
	return 0;
}


int TCPNetShare::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 << "tcp push data-------------------------size:" << m_arrData.size() << endl;
	m_lock.UnLock();
	return m_arrData.size();
}

//���ͼ��ʱ��
bool TCPNetShare::SetSleepTime(int time)
{
	m_SleepTime = time;
	return true;
}

//发送数据时制定每次发送的大小
int SendBuffer(int sock, unsigned char* buf, int nSize, int nFlagSize)
{
	int t_nCount = nSize / nFlagSize;
	int t_nMod = nSize % nFlagSize;
	unsigned char* buffer;
	int nSendSize = 0;
	if(nSize > nFlagSize)
		buffer = (unsigned char*)malloc(nFlagSize);
	else
		buffer = (unsigned char*)malloc(nSize);

	if (t_nMod != 0)
		t_nCount += 1;

	for(int i = 1; i <= t_nCount; i++)
	{
		if(i < t_nCount)
		{
			memcpy(buffer, buf + nFlagSize*(i - 1), nFlagSize);
			int ret = send(sock, (const char*)buffer, nFlagSize, 0);
			if(ret <= 0 || ret != nFlagSize)
				return ret;
			nSendSize += ret;
		}
		else
		{
			printf("finish\n");
			memcpy(buffer, buf + nFlagSize*(i - 1), nSize - nFlagSize*(i - 1));
			int ret = send(sock, (const char*)buffer, nSize - nFlagSize*(i-1), 0);
			if(ret <= 0 || ret != (nSize - nFlagSize*(i-1)))
				return ret;
			nSendSize += ret;
		}
		nsleep(10000);
	}
	return nSendSize;
}

#if 0
//发送数据
void SendNetData(int sock, char* fileData, int dwFileSize)  
{  
#if 0
    HANDLE  hFile;  
    DWORD   dwHighSize, dwBytesRead;  
    DWORD  dwFileSize;  
    hFile = CreateFile(_T(FILENAME), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);  
    dwFileSize = GetFileSize(hFile, &dwHighSize);  
    std::cout << "dwFileSize=" << dwFileSize << std::endl;  
    //2、读文件内容到 BYTE * fileData 中  
    BOOL bSuccess;  
    char *fileData = new char[dwFileSize];  
    bSuccess = ReadFile(hFile, fileData, dwFileSize, &dwBytesRead, NULL);  
    CloseHandle(hFile);  

    //3、判断文件是否成功读取  
    if (!bSuccess || (dwBytesRead != dwFileSize))  
    {  
        std::cout << "读取失败" << std::endl;;  
        free(fileData);  
        return;  
    }  
#endif    
   //发送数据帧  
    int  retval = 0;  
    unsigned int   DataPos = 0;  
    char   *eachBuf = new char[BLOCK_DATA_SIZE + 2 * FILE_HEAD];  
    memset(eachBuf, 0, BLOCK_DATA_SIZE + 2 * FILE_HEAD);  
    eachBuf[DataPos++] = BEGIN_NUM >> 24 & 0xff;//文件起始标识符  
    eachBuf[DataPos++] = BEGIN_NUM >> 16 & 0xff;  
    eachBuf[DataPos++] = BEGIN_NUM >> 8 & 0xff;  
    eachBuf[DataPos++] = BEGIN_NUM & 0xff;  
    eachBuf[DataPos++] = dwFileSize >> 24 & 0xff;  
    eachBuf[DataPos++] = dwFileSize >> 16 & 0xff;  
    eachBuf[DataPos++] = dwFileSize >> 8 & 0xff;  
    eachBuf[DataPos++] = dwFileSize & 0xff;  
    retval = send(sock, eachBuf, 2 * FILE_HEAD, 0);  
    int start = clock();  
    {  
        retval = send(sock, fileData, dwFileSize, 0);  
        if (retval == -1)  
            std::cout << "send error!";  
        int end = clock();  
    }  
} 
#endif

/*
	知识点::
	TCP发送的数据包会根据网络状况自动调整每个socket包的大小,
	UDP数据包不会,每次你发送多大的包就会接受多大的包,但是数据包不能太大最大是65000
*/
void* IdleSendThread(void* pArgs)
{
	TCPNetShare *pShare = (TCPNetShare*)pArgs;
	if (pShare != NULL)
	{
		int nIndex = 0;
		while (1)
		{
			if (!pShare->GetStatus())
				continue;

			if (pShare->m_arrData.size() > 0)
			{
				pShare->m_lock.Lock();
				std::vector<std::map<int, char*>>::iterator iterData = pShare->m_arrData.begin();
				{
					cout << "Send Heade----------------------------------------------------------------new ---------------------" << sizeof(NetData) << endl;
					std::map<int, char*>::iterator iterMap = iterData->begin();
					//in this we should insert some distinguish code to recognize the start data
					unsigned char* tmpData = (unsigned char*)malloc(iterMap->first + 14);
					memset(tmpData, '\0', iterMap->first + 14);
					tmpData[0] = '0';
					tmpData[1] = '1';
					tmpData[2] = '1';
					tmpData[3] = 'A';
					tmpData[4] = 'D';
					cout << "world :" << tmpData << endl;
					char tmpSize[10] = "";
					sprintf(tmpSize, "%09d", iterMap->first);
					cout << "hello :" << tmpSize << endl;
					memcpy(tmpData + 5, tmpSize, 9);

					//NetData tmpNetData;
					//tmpNetData.buffer = tmpData;
					//cout << "size begin: " << sizeof(tmpNetData);
					//cout << "size end: " << sizeof(tmpNetData);
					
					cout << "summer :" << tmpData << endl;
					
					memcpy(tmpData + 14, iterMap->second, iterMap->first);
					//int ret = send(pShare->m_pClient->sock, (const char*)(iterMap->second), iterMap->first, 0);
					//while(!send(pShare->m_pClient->sock, tmpData, iterMap->first + 14, 0))
					//{}
					int ret = SendBuffer(pShare->m_pClient->sock, tmpData, iterMap->first + 14, 165000);
					
					//int ret = send(pShare->m_pClient->sock, tmpData, iterMap->first + 14, 0);
			
					if (ret == (iterMap->first+14))
					{
						printf("Send %d OK To Client\n", nIndex);
						nIndex++;
						cout << "Send size:" << iterMap->first << endl; 
					}
					else
					{
						cout << "Send ===================================================Error" << endl;
						nIndex++;
					}
					char chBuf[20];
					sprintf(chBuf, "./jpg/img%d.jpg", nIndex);
					cout << chBuf << endl;
					FILE * fp = fopen(chBuf, "wb+");
					if (fp == NULL)
					{
						cout << "error open file" << endl;
					}
					fwrite(iterMap->second, 1, iterMap->first, fp);
					fclose(fp);
					nsleep(20000);
					free(tmpData);
					free(iterMap->second);
					//nsleep(pShare->GetClientSleep() * 1000);

				#if 0
					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)
					{
						cout << "data size----------------------------------" << t_nCount << endl;
						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 = send(pShare->m_pClient->sock, (const char*)&pack, sizeof(NetData), 0);
						if (ret > 0)
						{
							printf("Send %d OK To Server\n", pack.nIndex);
							cout << "size:" << pack.nBufSize << endl; 
						}
						
						nsleep(pShare->GetClientSleep());
					}
					free(iterMap->second);
					#endif

					pShare->m_arrData.erase(iterData);
					cout << "pop data**************************size:" << pShare->m_arrData.size() << endl;
					pShare->m_lock.UnLock();
					printf("finish--\n");
				}
			}
			else
			{	
				//char tmpData[5];
				//tmpData[0] = '0';
				//tmpData[1] = '1';
				//tmpData[2] = 'e';
				//tmpData[3] = 'n';
				//tmpData[4] = 'd';
				//int ret = send(pShare->m_pClient->sock, tmpData, 5, 0);
				nsleep(10);
			}
		}
	}
	return NULL;
}

#if 0

void* IdleSendStruThread(void* pArgs)
{
	TCPNetShare *pShare = (TCPNetShare*)pArgs;
	if (pShare != NULL)
	{
		int nIndex = 0;
		while (1)
		{
			if (!pShare->GetStatus())
				continue;

			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();
					//in this we should insert some distinguish code to recognize the start data
					char* tmpData = (char*)malloc(iterMap->first);
					memcpy(tmpData, iterMap->second, iterMap->first);
					free(iterMap->second);
					pShare->m_arrData.erase(iterData);
					pShare->m_lock.UnLock();
					
					NetData tmpSendData;
					tmpSendData.nBufSize = iterMap->first;
					//tmpSendData.buffer = tmpData;
														
				}
			}
		}
	}
	return NULL;
}

void* IdleNetSendThread(void* pArgs)
{
	TCPNetShare *pShare = (TCPNetShare*)pArgs;
	if (pShare != NULL)
	{
		int nIndex = 0;
		while (1)
		{
			if (!pShare->GetStatus())
				continue;

			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();
					//in this we should insert some distinguish code to recognize the start data
					char* tmpData = (char*)malloc(iterMap->first);
					memcpy(tmpData, iterMap->second, iterMap->first);
					int nSize = iterMap->first;
					free(iterMap->second);
					pShare->m_arrData.erase(iterData);
					pShare->m_lock.UnLock();	
					SendNetData(pShare->m_pClient->sock, tmpData, nSize);								
				}
			}
			else
			{
				nsleep(10);			
			}
		}
	}
	return NULL;
}

#endif

TCPNetShare::TCPNetShare(TCPClient* client)
{
	m_pClient = client;
	int send_size = 1000000;
	int optlen = 4;
	setsockopt(m_pClient->sock, SOL_SOCKET, SO_SNDBUF, (void*)&send_size, optlen);
	//create thread to send data
	//��������ѭ���߳�
#if 1
	pthread_t pid;
	if (pthread_create(&pid, NULL, IdleSendThread, this) != 0)
	{
		cout << "thread tcp send round create failed" << endl;
	}
	else
	{
		pthread_detach(pid);
		cout << "thread tcp send round create success" << endl;
	}
#endif
#if 0
	pthread_t pid;
	if (pthread_create(&pid, NULL, IdleSendStruThread, this) != 0)
	{
		cout << "thread tcp send round create failed" << endl;
	}
	else
	{
		pthread_detach(pid);
		cout << "thread tcp send round create success" << endl;
	}
#endif

#if 0
	pthread_t pid;
	if (pthread_create(&pid, NULL, IdleNetSendThread, this) != 0)
	{
		cout << "thread tcp send round create failed" << endl;
	}
	else
	{
		pthread_detach(pid);
		cout << "thread tcp send round create success" << endl;
	}
#endif
}


TCPNetShare::~TCPNetShare()
{

}

#ifndef _SYS_FUN_H__
#define _SYS_FUN_H__
#ifdef WIN32
#include <windows.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>
#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

CC = g++ -std=c++11


cflags = -I. #./libevent/include
INC = -L. #libevent/lib


SRCS = MultiNetUtil.cpp TCPNetShare.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 <iostream>
#include "MultiNetUtil.h"

#ifdef WIN32
#pragma comment(lib, "libNetUtilTCP.lib")
#endif

using namespace std;

int main(void)
{
	MultiNetUtil *pUtil = createNetUtil();
	if (pUtil == NULL)
	{
		cout << "Create NetUtil Error" << endl;
		return -1;
	}

	pUtil->InitSocket(6666);

	pUtil->SetSleepTime(30);

	//��ӽ��ܶ�
	for(int i = 0; i < 1; i++)
	{
		int num = pUtil->InsertChannel(0+i, 9999+i, "127.0.0.1");
		cout << "remain channel: " << num << endl;
	}
	//���뷢������
	int nChannel = 0;
	int nIndex = 0;
	char chBuf[100] = "123456hg";
	for (int i = 1; i < 41; i++)
	{
		sprintf(chBuf, "/home/long/Databases/netimg/sendimg/%d.jpg", i);
		//sprintf(chBuf, "/home/long/sff.mp4", i);
		cout << chBuf << endl;
		FILE * fp = fopen(chBuf, "rb+");
		if (fp == NULL)
		{
			cout << "error open file" << 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);
		memset(tmpBuf, '\0', size);
		fread(tmpBuf, 1, size, fp);
		if(pUtil->HasChannel(nChannel))
		{
			int num = pUtil->PushData(nChannel, size, tmpBuf);
		        cout << "remain size--" << num << endl;	
		}
		else
		{
			cout << "has no channel: " << nChannel << endl;
			usleep(100000);
			free(tmpBuf);			
		}
	
		fclose(fp);
		nChannel++;
		if (nChannel == 1)
			nChannel = 0;

		nIndex++;
		if(nIndex == 40)
			break;
		nsleep(3000);
		if (i == 40)
			i = 1;
	}
	
	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

客户端和服务端源文件地址:

源码中有点问题,有一个宏定义写错了

#define BYTE unsigned char*

改成

#define BYTE unsigned char

否则收到文件出错

https://download.csdn.net/download/chnim/10499725


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

telllong

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

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

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

打赏作者

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

抵扣说明:

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

余额充值