Windows平台上实现P2P服务(四)

建立一个链式结构便于存储用户信息,以便今后处理登录和未登录的信息。首先我们建立一个用户信息的结构:

/// <summary>客户端信息结构</summary>
typedef struct _client *lp_client;
/// <summary>客户端信息指针结构</summary>
typedef struct _client
{
	char userName[20];		//用户名称
	char userPassword[20];	//用户口令
	char appCode[20];		//应用编码
	char machineCode[32];	//机器码
	char runtimeCode[32];	//运行码
	struct  in_addr addr;	//网址
	u_short port;			//通讯端口
	lp_client next;			//链表下一个
};

153123_gAAr_2308182.png如图所示,所谓链式结构就是左侧图示的方式,从上面的结构上看,最后那个next就是用于链接的,为了更好的操作这个链接,我们需要建立两个变量来便于操作和处理,这两个变量是根节点和末节点变量。

/// <summary>客户信息列表根节点</summary>
lp_client rootItem = NULL;
/// <summary>客户信息列表末节点</summary>
lp_client lastItem = NULL;

下面提供一下整个代码,包含查询、增加、删除等操作。

UDPList.h

#pragma once
#include "targetver.h"

/// <summary>信息结构的指针型</summary>
typedef struct _message *lp_message;
/// <summary>信息结构</summary>
typedef struct _message
{
	union {
		struct { char buff[1030]; };
		struct { char cmd[6]; char rt_code[32]; char data[992]; };
	};
	SOCKADDR_IN addr;
};
/// <summary>客户端信息结构</summary>
typedef struct _client *lp_client;
/// <summary>客户端信息指针结构</summary>
typedef struct _client
{
	char userName[20];		//用户名称
	char userPassword[20];	//用户口令
	char appCode[20];		//应用编码
	char machineCode[32];	//机器码
	char runtimeCode[32];	//运行码
	struct  in_addr addr;	//网址
	u_short port;			//通讯端口
	lp_client next;			//链表下一个
};

/// <summary>根据用户名称得到用户信息节点</summary>
lp_client IndexOf(char* appCode, char * userName);
/// <summary>根据用户名称得到用户信息节点</summary>
lp_client IndexOf(char* appCode, char * userName, char * machineCode);
/// <summary>根据运行编码得到用户信息节点</summary>
lp_client IndexOf(char * runtimeCode);
/// <summary>添加一个客户端信息</summary>
lp_client addClient(char* userName, char* userPassword, char* appCode, char* machineCode);
/// <summary>添加一个客户端信息</summary>
void addClient(lp_client client);
/// <summary>一个客户端登录系统</summary>
lp_client regClient(char * userName, char * userPassword, char * appCode, struct  in_addr addr, u_short port);
/// <summary>一个客户端登录系统</summary>
lp_client regClient(char * userName, char * userPassword, char * appCode, char * machineCode, struct  in_addr addr, u_short port);
/// <summary>根据用户名称删除用户信息节点</summary>
void removeClient(char* appCode, char * userName);
/// <summary>从文件缓存中提取客户端列表</summary>
void loadFromFile(char* filename);
/// <summary>将客户端列表写入缓存文件</summary>
void saveToFile(char* filename);

下面是UDPList.cpp

#include "stdafx.h"
#include "UDPList.h"

/// <summary>客户信息列表根节点</summary>
lp_client rootItem = NULL;
/// <summary>客户信息列表末节点</summary>
lp_client lastItem = NULL;

void setRuntimeCode(lp_client client)
{
	GUID gid;
	CoCreateGuid(&gid);
	sprintf(client->runtimeCode, "%08x%04x%04x%02x%02x%02x%02x%02x%02x%02x%02x", gid.Data1, gid.Data2, gid.Data3, gid.Data4[0], gid.Data4[1], gid.Data4[2], gid.Data4[3], gid.Data4[4], gid.Data4[5], gid.Data4[6], gid.Data4[7]);
}
/// <summary>根据用户名称得到用户信息节点</summary>
lp_client IndexOf(char* appCode, char * userName)
{
	if (rootItem == NULL)return NULL;
	lp_client tmp = rootItem;
	while (tmp)
	{
		if (strcmp(tmp->appCode, appCode) == 0 && strcmp(tmp->userName, userName) == 0)
			return tmp;
		tmp = tmp->next;
	}
	return NULL;
}
/// <summary>根据用户名称得到用户信息节点</summary>
lp_client IndexOf(char* appCode, char * userName, char * machineCode)
{
	if (rootItem == NULL)return NULL;
	lp_client tmp = rootItem;
	while (tmp)
	{
		if (strncmp(tmp->appCode, appCode, 20) == 0 && strncmp(tmp->userName, userName, 20) == 0 && strncmp(tmp->machineCode, machineCode, 32) == 0)
			return tmp;
		tmp = tmp->next;
	}
	return NULL;
}
/// <summary>根据运行编码得到用户信息节点</summary>
lp_client IndexOf(char * runtimeCode)
{
	if (rootItem == NULL)return NULL;
	lp_client tmp = rootItem;
	while (tmp)
	{
		if (strcmp(tmp->runtimeCode, runtimeCode) == 0)
			return tmp;
		tmp = tmp->next;
	}
	return NULL;
}
/// <summary>一个客户端登录系统</summary>
lp_client regClient(char * userName, char * userPassword, char * appCode, struct  in_addr addr, u_short port)
{
	lp_client result = IndexOf(userName, userPassword);
	if (result == NULL)return NULL;
	if (strcmp(result->userPassword, userPassword) != 0)return NULL;
	result->addr = addr;
	result->port = port;
	setRuntimeCode(result);
	return result;
}
/// <summary>一个客户端登录系统</summary>
lp_client regClient(char * userName, char * userPassword, char * appCode, char * machineCode, struct  in_addr addr, u_short port)
{
	lp_client result = IndexOf(appCode, userName, machineCode);
	if (result == NULL)return NULL;
	if (strcmp(result->userPassword, userPassword) != 0)return NULL;
	result->addr = addr;
	result->port = port;
	setRuntimeCode(result);
	return result;
}
/// <summary>根据用户名称删除用户信息节点</summary>
void removeClient(char * appCode, char * userName)
{
	if (rootItem == NULL)return ;
	lp_client tmp = rootItem;
	lp_client parent = NULL;
	while (tmp)
	{
		if (strcmp(tmp->appCode, appCode) == 0 && strcmp(tmp->userName, userName) == 0)
		{
			if (parent == NULL)rootItem = tmp->next;
			else parent->next = tmp->next;
			if (tmp->next == NULL)lastItem = parent;
			free(tmp);
			return;
		}
		parent = tmp;
		tmp = tmp->next;
	}
}
/// <summary>从文件缓存中提取客户端列表</summary>
void loadFromFile(char * filename)
{
	FILE *fp;
	if ((fp = fopen(filename, "rb")) == NULL)
	{
		printf("cant open the file");
		exit(0);
	}
	lp_client client = (lp_client)malloc(sizeof(_client));
	memset(client, 0, sizeof(_client));
	while(fread(client, 20 + 20 + 20 + 32, 1, fp) > 0) {
		if (rootItem == NULL)rootItem = client;
		else lastItem->next = client;
		lastItem = client;
		client = (lp_client)malloc(sizeof(_client));
		memset(client, 0, sizeof(_client));
	}
	free(client);
	fclose(fp);
}
/// <summary>将客户端列表写入缓存文件</summary>
void saveToFile(char * filename)
{
	FILE * outfile = fopen(filename, "wb");
	if (outfile == NULL)
	{
		printf("cant open the file");
		exit(0);
	}
	lp_client client = rootItem;
	while (client)
	{
		fwrite(client, 20 + 20 + 20 + 32, 1, outfile);
		client = client->next;
	}
	fclose(outfile);
}
/// <summary>添加一个客户端信息</summary>
lp_client addClient(char* userName, char* userPassword, char* appCode, char* machineCode)
{
	lp_client result = IndexOf(userName, userPassword);
	if (result != NULL)return result;
	result= (lp_client)malloc(sizeof(_client));
	memset(result, 0, sizeof(_client));
	strcpy(result->userName, userName);
	strcpy(result->userPassword, userPassword);
	strcpy(result->appCode, appCode);
	strcpy(result->machineCode, machineCode);
	addClient(result);
	return result;
}
/// <summary>添加一个客户端信息</summary>
void addClient(lp_client client)
{
	if (rootItem == NULL)rootItem = client;
	else lastItem->next = client;
	lastItem = client;
}

同时函数还实现了文件缓存功能,通过SaveToFile和LoadFromFile来实现。

转载于:https://my.oschina.net/u/2308182/blog/1480129

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值