网络流量计费程序

输入文件:

S:SvrID=6, User=200, TimeStamp=2013-5-24 07:30:00, Event=Login
S:SvrID=6, User=100, TimeStamp=2013-5-24 07:59:30, Event=Login
S:SvrID=6, User=100, TimeStamp=2013-5-24 07:59:59, Event=Logout
S:SvrID=4, User=100, TimeStamp=2013-5-24 08:00:00, Event=Login
T:SvrID=4, User=100, TimeStamp=2013-5-24 08:02:30, Url=www.taobao.com, Method=Post, Flow=15
T:SvrID=4, User=100, TimeStamp=2013-5-24 08:03:00, Url=www.taobao.com/shop1234, Method=Get, Flow=200
T:SvrID=6, User=200, TimeStamp=2013-5-24 08:05:00, Url=www.sina.com.cn, Method=Get, Flow=200
T:SvrID=4, User=100, TimeStamp=2013-5-24 08:06:00, Url=www.vmall.com, Method=Post, Flow=20
S:SvrID=6, User=200, TimeStamp=2013-5-24 08:08:34, Event=Logout
T:SvrID=4, TimeStamp=2013-5-24 08:08:00, Url=www.vmall.com/mobile/d2, Method=Get, Flow=500, User=100
T:SvrID=8, User=100, TimeStamp=2013-5-24 08:09:10, Url=www.vmall.com/wideband, Method=Post, Flow=50
T:SvrID=4, User=100, TimeStamp=2013-5-24 08:10:20, Url=www.taobao.com/shop5678, Method=Get, Flow=350
T:SvrID=4, User=100, TimeStamp=2013-5-24 08:12:00, Url=www.tudou.com, Method=Post, Flow=43
T:SvrID=4, User=100, TimeStamp=2013-5-24 08:12:15, Url=www.tudou.com/movie4, Method=Get, Flow=2048
T:SID=4, TimeStamp=2013-5-24 08:15:00, Url=www.taobao.com/item982738729374283424, Method=Get, Flow=20
S:SvrID=4, User=100, TimeStamp=2013-5-24 08:19:59, Event=Logout
T:SvrID=4, User=100, TimeStamp=2013-5-24 08:20:15, Url=www.taobao.com/shop86, Method=Post, Flow=35

输出文件:ID,在线时长,url条数

100,1228,3
www.taobao.com,15,550
www.tudou.com,43,2048
www.vmall.com,20,500
200,2314,1
www.sina.com.cn,0,200

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define MAX_LINE_LENTH 10240
#define MAX_URL_ROOT 10240
#define TIME_LOW_LEVEL 20080101000000
#define TIME_HIGH_LEVEL 20201231235959
#define MAX_MESSAGE 100000
/************************************************************************/
/* inFile & outFile 有效性由用例保证,请不要在函数中关闭这2个文件                                                                     */
/************************************************************************/
enum messageType {state=1,text};
enum mEventType {login=1, logout};
enum mMethodType {post=1, get};
int userAmount = 0;
int messageCount = 0;

struct urlInfo {
 char url[1024];
 int post;
 int get;
 struct urlInfo* next;
};
struct userInfo {
 int userID;
 int duration;
 int urlItems;
 struct urlInfo* urlInfoList;
};
struct message {
 enum messageType type;
 int serverID;
 int userID;
 char timeStamp[128];
 enum mEventType mEvent;
 char url[1024];
 enum mMethodType mMethod;
 int flow;
 struct message* next;
};
struct userNode {
 struct message* messageHead;
 int userID;
 int serverID;
 enum mEventType mEvent;
 struct userNode* nextUserNode;
};
int readLine(FILE** fp, char* line)
{
 char c;
 int i = 0;
 c = fgetc(*fp);
 while(c!='\n' && !feof(*fp)){
  line[i] = c;
  i++;
  c = fgetc(*fp);
  if( i>=MAX_LINE_LENTH ) {
   line[i]='\0';
   break;
  }
 }
 return i;
}
bool checkKeyword(struct message* pMessage, char* keyword, char* value)
{
 char urlRoot[MAX_URL_ROOT] = {0};
 if(0 == _stricmp(keyword, "SvrID")) {
  pMessage->serverID = atoi(value);
 } else if(0 == _stricmp(keyword, "User")) {
  pMessage->userID = atoi(value);
 } else if(0 == _stricmp(keyword, "TimeStamp")) {
  strncpy_s(pMessage->timeStamp, value, sizeof(pMessage->timeStamp)-1);
  pMessage->timeStamp[sizeof(pMessage->timeStamp)-1] = '\0';
 } else if(pMessage->type == state) {
  if(0 == _stricmp(keyword, "Event")) {
   if(0 == _stricmp(value, "Login"))
    pMessage->mEvent = login;
   else if(0 == _stricmp(value, "Logout"))
    pMessage->mEvent = logout;
   else
    return false;
  } else
   return false;
 } else if(pMessage->type == text) {
  if(0 == _stricmp(keyword, "Url")) {
   sscanf_s(value, "%[^/]", urlRoot, sizeof(pMessage->url)-1);
   strncpy_s(pMessage->url, urlRoot, sizeof(pMessage->url)-1);
   pMessage->url[sizeof(pMessage->url)-1] = '\0';
  } else if(0 == _stricmp(keyword, "Method")) {
   if(0 == _stricmp(value, "Post"))
    pMessage->mMethod = post;
   else if(0 == _stricmp(value, "Get"))
    pMessage->mMethod = get;
   else
    return false;
  } else if(0 == _stricmp(keyword, "Flow")) {
   pMessage->flow = atoi(value);
  } else
   return false;
 } else
  return false;
 return true;
}

bool isLegal(struct message* pMessage)
{
	char* urlPoint = NULL;
	size_t urlLength = 0;
	int year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0;
	__int64 sum = 0;

	if(pMessage->serverID<1 || pMessage->serverID>100)
		return false;
	if(pMessage->userID<1 || pMessage->userID>10000)
		return false;
	if(*(pMessage->timeStamp) == NULL) {
		return false;
	} else {
		sscanf_s(pMessage->timeStamp, "%d-%d-%d %d:%d:%d", &year, &month, &day, &hour, &minute, &second);
		sum = year*10000000000+month*100000000+day*1000000+hour*10000+minute*100+second;
		if(sum<TIME_LOW_LEVEL || sum>TIME_HIGH_LEVEL)
			return false;

	}
	if(pMessage->type == state) {
		if(pMessage->mEvent == 0)
			return false;
	} else if (pMessage->type == text) {
		if(*(pMessage->url) == NULL) {
			return false;
		} else {
			urlPoint = pMessage->url;
			urlLength = strlen(pMessage->url);


			if(urlPoint[0]!='w' || urlPoint[1]!='w' ||urlPoint[2]!='w' || urlPoint[3]!='.')
				return false;
			/*
			else {
				urlPoint = urlPoint + urlLength - strlen(".com.cn");
				if (urlPoint[0]!='.' || urlPoint[1]!='c' ||urlPoint[2]!='o' || urlPoint[3]!='m'||
					urlPoint[4]!='.' ||urlPoint[5]!='c' || urlPoint[6]!='n') {
					urlPoint = pMessage->url;
					urlPoint = urlPoint + urlLength - strlen(".com");
					if(urlPoint[0]!='.' || urlPoint[1]!='c' ||urlPoint[2]!='o' || urlPoint[3]!='m')
						return false;
				}
			}*/
		}
		if(pMessage->mMethod == 0)
			return false;
		if(pMessage->flow <= 0)
			return false;
	} else 
		return false;
	return true;
}
 
struct message* parseLine(char* line)
{
	char* pToken = NULL;
	char* pNext = NULL;
	struct message* pMessage = NULL;
	char keyword[128] = {0};
	
	pMessage = (struct message*) malloc(sizeof(struct message));
	if(pMessage == NULL)
		return NULL;
	memset(pMessage, 0, sizeof(struct message));

	pToken = strtok_s(line, ":", &pNext);
	if(0 == _stricmp(pToken, "s")) {
		pMessage->type = state;
	} else if (0 == _stricmp(pToken, "t")) {
		pMessage->type = text;
	} else {
		goto parse_error;
	}

	while((pToken=strtok_s( NULL, ",", &pNext)) != NULL) {
		while(pToken[0] == ' ') {
			pToken++;
		}
		sscanf_s(pToken, "%[^=]", keyword, 128) ;
		keyword[sizeof(keyword)-1] = '\0';
		pToken = pToken+strlen(keyword)+1;
		if(pToken!=NULL)
			checkKeyword(pMessage, keyword, pToken);

		memset(keyword, 0, sizeof(keyword));
	}
	if(!isLegal(pMessage))
		goto parse_error;

	return pMessage;
parse_error:
	free(pMessage);
	return NULL;
}
 
 

void addToMessageList(struct message* messageHead, struct message* pMessage) { struct message* messagePoint = NULL; struct message* lastPoint = NULL; messagePoint = messageHead->next; //lastPoint = messageHead; while(messagePoint->next != NULL) { /* if(strcmp(pMessage->url,messagePoint->url) >= 0) { lastPoint->next = pMessage; pMessage->next = messagePoint; return; } else { lastPoint = messagePoint; messagePoint = messagePoint->next; } */ messagePoint = messagePoint->next; } messagePoint->next = pMessage; }
 


void addToUserList(struct userNode* userNodeHead, struct message* pMessage)
{
	struct userNode* userPoint = NULL;
	struct userNode* lastUserPoint = NULL;
	userPoint = userNodeHead->nextUserNode;
	lastUserPoint = userNodeHead;


	while(userPoint != NULL) {
		if(userPoint->userID == pMessage->userID) {
			if((pMessage->type==text) && ((userPoint->serverID!=pMessage->serverID) || (userPoint->mEvent!=login))) {
				free(pMessage);
				return;
			}
			if(userPoint->messageHead == NULL) {
				userPoint->messageHead = (struct message*) malloc(sizeof(struct message));
				if(!userPoint->messageHead)
					return;
				memset(userPoint->messageHead, 0, sizeof(struct message));
				userPoint->messageHead->next = pMessage;
				if(pMessage->type == state)
					userPoint->mEvent = pMessage->mEvent; 
			} else {
				addToMessageList(userPoint->messageHead, pMessage);
				if(pMessage->type == state) {
					userPoint->mEvent = pMessage->mEvent;
					if(pMessage->mEvent == login) {
						userPoint->serverID = pMessage->serverID;
					}
				}

			}
			return;
		} else if (pMessage->userID > userPoint->userID) {
			lastUserPoint = userPoint;
			userPoint = userPoint->nextUserNode;
		} else if (pMessage->userID < userPoint->userID) {
			break;
		}
	}

	lastUserPoint->nextUserNode = (struct userNode*)malloc(sizeof(struct userNode));
	if(!lastUserPoint->nextUserNode)
		return;
	memset(lastUserPoint->nextUserNode, 0, sizeof(struct userNode));
	lastUserPoint->nextUserNode->userID = pMessage->userID;
	if(pMessage->type == state) {
		lastUserPoint->nextUserNode->mEvent = pMessage->mEvent;
		if(pMessage->mEvent == login) {
			lastUserPoint->nextUserNode->serverID = pMessage->serverID;
		}
	}
	lastUserPoint->nextUserNode->userID = pMessage->userID;
	lastUserPoint->nextUserNode->messageHead = (struct message*) malloc(sizeof(struct message));
	if(!lastUserPoint->nextUserNode->messageHead)
		return;

	memset(lastUserPoint->nextUserNode->messageHead, 0, sizeof(struct message));
	lastUserPoint->nextUserNode->messageHead->next = pMessage;
	lastUserPoint->nextUserNode->nextUserNode = userPoint;
	userAmount++;
}
void releaseMessageList(struct message* messageHead)
{
	struct message* messagePoint = NULL;
	struct message* lastMessagePoint = NULL;

	lastMessagePoint = messageHead;
	messagePoint = messageHead->next;

	while(messagePoint != NULL) {
		free(lastMessagePoint);
		lastMessagePoint = messagePoint;
		messagePoint = messagePoint->next;
	}
}
void releaseUserList(struct userNode* userNodeHead)
{
	struct userNode* userPoint = NULL;
	struct userNode* lastUserPoint = NULL;

	lastUserPoint = userNodeHead;
	userPoint = userNodeHead->nextUserNode;
	while(userPoint != NULL) {
		if(lastUserPoint->messageHead!=NULL)
			releaseMessageList(lastUserPoint->messageHead);
		free(lastUserPoint);
		lastUserPoint = userPoint;
		userPoint = userPoint->nextUserNode;
	}
}

 
 
 
int convertDuration(char* loginTime, char* logoutTime)
{
	int loginYear = 0, loginMonth = 0, loginDay = 0, loginHour = 0, loginMinute = 0, loginSecond = 0;
	int logoutYear = 0, logoutMonth = 0, logoutDay = 0, logoutHour = 0, logoutMinute = 0, logoutSecond = 0;
	int duration = 0;
	sscanf_s(loginTime, "%d-%d-%d %d:%d:%d", &loginYear, &loginMonth, &loginDay, &loginHour, &loginMinute, &loginSecond);
	sscanf_s(logoutTime, "%d-%d-%d %d:%d:%d", &logoutYear, &logoutMonth, &logoutDay, &logoutHour, &logoutMinute, &logoutSecond);
	//TO DO 
	duration = (logoutYear-loginYear)*365*24*60*60 + (logoutMonth-loginMonth)*30*24*60*60 + (logoutDay-loginDay)*24*60*60 + (logoutHour-loginHour)*60*60 + (logoutMinute-loginMinute)*60 + (logoutSecond-loginSecond);
	return duration;

}
int calculateDuration(struct message* messageHead)
{
	struct message* messagePoint = NULL;
	int duration = 0;
	int userState = 0;
	char loginTime[64] = {0};
	char logoutTime[64] = {0};
	messagePoint = messageHead->next;
	while(messagePoint != NULL) {
		if(messagePoint->type==state && messagePoint->mEvent == login) {
			memset(loginTime, 0, sizeof(loginTime));
			strncpy_s(loginTime, messagePoint->timeStamp, sizeof(loginTime)-1);
			loginTime[sizeof(loginTime)-1] = '\0';
			userState++;
		} else if(messagePoint->type==state && messagePoint->mEvent == logout) {
			memset(logoutTime, 0, sizeof(logoutTime));
			strncpy_s(logoutTime, messagePoint->timeStamp, sizeof(logoutTime)-1);
			logoutTime[sizeof(logoutTime)-1] = '\0';
			if(userState == 1) {
				duration += convertDuration(loginTime, logoutTime);
			}
			userState = 0;
		}
		messagePoint = messagePoint->next;
	}
	return duration;
}

int calculateUrlItems(struct urlInfo* urlInfoHead)
{
	struct urlInfo* urlInfoPoint;
	int urlItems = 0;
	urlInfoPoint = urlInfoHead;
	while(urlInfoPoint!=NULL) {
		urlInfoPoint = urlInfoPoint->next;
		urlItems++;
	}
	/* reduce headPoint */
	urlItems--;
	return urlItems;
}

void addToUrlInfoList(struct urlInfo* urlInfoHead, struct message* messagePoint)
{
	struct urlInfo* urlInfoPoint = NULL;
	struct urlInfo* lastUrlInfoPoint = NULL;
	urlInfoPoint = urlInfoHead->next;
	lastUrlInfoPoint = urlInfoHead;
	while(urlInfoPoint != NULL) {
		if(_stricmp(urlInfoPoint->url, messagePoint->url) == 0) {
			if(messagePoint->mMethod == post) {
				urlInfoPoint->post += messagePoint->flow;
			} else if(messagePoint->mMethod == get) {
				urlInfoPoint->get += messagePoint->flow;
			}
			return;
		} else if(_stricmp(urlInfoPoint->url, messagePoint->url) < 0) {
			lastUrlInfoPoint = urlInfoPoint;
			urlInfoPoint = urlInfoPoint->next;
		} else if(_stricmp(urlInfoPoint->url, messagePoint->url) > 0) {
			break;
		}
	}

	lastUrlInfoPoint->next = (struct urlInfo*) malloc(sizeof(struct urlInfo));
	if(!lastUrlInfoPoint->next)
		return;
	memset(lastUrlInfoPoint->next, 0, sizeof(struct urlInfo));
	strncpy_s(lastUrlInfoPoint->next->url, messagePoint->url, sizeof(lastUrlInfoPoint->next->url)-1);
	lastUrlInfoPoint->next->url[sizeof(lastUrlInfoPoint->next->url)-1] = '\0';
	if(messagePoint->mMethod == post) {
		lastUrlInfoPoint->next->post = messagePoint->flow;
	} else if(messagePoint->mMethod == get) {
		lastUrlInfoPoint->next->get = messagePoint->flow;
	}
	lastUrlInfoPoint->next->next = urlInfoPoint;
	
}
 
 
 
struct urlInfo* calculateUrlInfoList(struct message* messageHead)
{
	struct urlInfo* urlInfoHead = NULL;
	struct message* messagePoint = NULL;
	messagePoint = messageHead->next;

	urlInfoHead = (struct urlInfo*) malloc(sizeof(struct urlInfo));
	if(!urlInfoHead)
		return NULL;
	memset(urlInfoHead, 0, sizeof(struct urlInfo));

	while(messagePoint != NULL) {
		if(messagePoint->type == text) {
			addToUrlInfoList(urlInfoHead, messagePoint);
		}
		messagePoint = messagePoint->next;
	}
	return urlInfoHead;
}
void releaseUrlInfoList(struct urlInfo* urlInfoList)
{
	struct urlInfo* urlInfoPoint = NULL;
	struct urlInfo* lastUrlInfoPoint = NULL;
	lastUrlInfoPoint = urlInfoList;
	urlInfoPoint = urlInfoList->next;
	while(urlInfoPoint != NULL){
		free(lastUrlInfoPoint);
		lastUrlInfoPoint = urlInfoPoint;
		urlInfoPoint = urlInfoPoint->next;
	}
	
}
void releaseUserInfo(struct userInfo* userInfoArray)
{
	int i = 0;
	while(i<userAmount) {
		if(userInfoArray[i].urlInfoList != NULL)
			releaseUrlInfoList(userInfoArray[i].urlInfoList);
		i++;
	}
	free(userInfoArray);
}
void writeListToFile(struct urlInfo* urlInfoList, FILE* outFile)
{
	struct urlInfo* urlInfoPoint;
	urlInfoPoint = urlInfoList->next;
	while(urlInfoPoint != NULL) {
		fprintf(outFile,"%s,%d,%d\n", urlInfoPoint->url, urlInfoPoint->post, urlInfoPoint->get);
		urlInfoPoint = urlInfoPoint->next;
	}
}
void writeFile(struct userInfo* userInfoArray, FILE * outFile)
{
	int i = 0;
	while(i<userAmount) {
		fprintf(outFile,"%d,%d,%d\n", userInfoArray[i].userID, userInfoArray[i].duration, userInfoArray[i].urlItems);
		writeListToFile(userInfoArray[i].urlInfoList, outFile);
		i++;
	}
	//fputc(EOF, outFile);
}
void calculate(struct userNode* userNodeHead, FILE * outFile)
{
	int i = 0;
	struct userNode* userPoint = NULL;
	struct userInfo* userInfoArray = (struct userInfo*) malloc(sizeof(struct userInfo)*userAmount);
	if(!userInfoArray)
		return;
	memset(userInfoArray, 0, sizeof(struct userInfo)*userAmount);

	userPoint = userNodeHead->nextUserNode;
	while(i<userAmount) {
		userInfoArray[i].userID = userPoint->userID;
		userInfoArray[i].duration = calculateDuration(userPoint->messageHead);
		userInfoArray[i].urlInfoList = calculateUrlInfoList(userPoint->messageHead);
		userInfoArray[i].urlItems = calculateUrlItems(userInfoArray[i].urlInfoList);

		userPoint = userPoint->nextUserNode;
		i++;
	}
	
	writeFile(userInfoArray, outFile);
	
	if( userInfoArray!= NULL)
		releaseUserInfo(userInfoArray);

}

统计函数的入口:

void staticNetworkFlow(FILE * inFile, FILE * outFile)
{
    
	char* line = NULL;
	int lineLength = 0;
	struct userNode* userNodeHead = NULL;
	struct userNode* userListPoint = NULL;
	struct message* pMessage = NULL;
	userAmount = 0;
    messageCount = 0;
	
	while(!feof(inFile)) {
		line = (char*) malloc(sizeof(char)*MAX_LINE_LENTH);
		if(!line)
			return;
		memset(line, 0, sizeof(char)*MAX_LINE_LENTH);

		lineLength = readLine(&inFile, line);
		if(0 != lineLength) {
			pMessage = parseLine(line);
			if(pMessage != NULL) {
				if(userNodeHead == NULL) {
					userNodeHead = (struct userNode*)malloc(sizeof(struct userNode));
					if(!userNodeHead)
						return;
					memset(userNodeHead, 0, sizeof(struct userNode));
					userNodeHead->userID = 0;
					userNodeHead->nextUserNode = (struct userNode*)malloc(sizeof(struct userNode));
					if(!userNodeHead->nextUserNode)
						return;
					memset(userNodeHead->nextUserNode, 0, sizeof(struct userNode));
					userNodeHead->nextUserNode->userID = pMessage->userID;
					if(pMessage->type == state) {
						userNodeHead->nextUserNode->mEvent = pMessage->mEvent;
						if(pMessage->mEvent == login) {
							userNodeHead->nextUserNode->serverID = pMessage->serverID;
						}
					}
					userAmount++;
				}
				addToUserList(userNodeHead, pMessage);
			}
			messageCount++;
		}

		free(line);
		if(messageCount >= MAX_MESSAGE)
			break;
	}

	calculate(userNodeHead, outFile);


	if(userNodeHead)
		releaseUserList(userNodeHead);



	return;


}

2013年5月27日上传

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值