文档章节

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

jamesvon
 jamesvon
发布于 2017/07/22 15:52
字数 1247
阅读 19
收藏 0

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

/// <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;			//链表下一个
};

如图所示,所谓链式结构就是左侧图示的方式,从上面的结构上看,最后那个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来实现。

© 著作权归作者所有

共有 人打赏支持
jamesvon
粉丝 3
博文 31
码字总数 47875
作品 0
河西
项目经理
私信 提问
P2P计算平台--JXTA

JXTA是一个用来解决P2P计算的开放的网络计算平台。JXTAP2P平台使开发者在其上建立P toP的应用。2001年4月,发布了第一个源型实现,它是基于JDK1.1.4的。 现有的P2P系统有一些缺陷,大多数P2P...

匿名
2009/04/06
7.5K
0
阿里云上线视频云剪辑 快速产出PGC短视频不再是问题!

摘要: PCDN相对于CDN拥有成本更低、质量更好两方面的核心优势。本文将为大家详细介绍PCDN的定义、名词、功能、架构、场景和优势。 写在前面: CDN是目前广泛应用于视频云行业的内容分发加速...

音染
2017/07/21
55
0
OpenVPN中TAP-win32d的net30问题

OpenVPN中有个topology参数,该参数控制了tun模式下如何为OpenVPN客户端分配虚拟IP地址。在OpenVPN的manpage中,明确指出tun模式下对于windows平台不能使用p2p拓扑,有人说这是没有必要的,因...

晨曦之光
2012/04/10
577
0
有了WCF,Socket是否已人老珠黄?

1. Socket相关背景   Socket,中文译为“套接字”,最早在UNIX中引入并得到广泛应用,后来微软在设计Windows时引入了UNIX中的这个概念和相应的设计理念,并针对Windows的特性略作调整,形成...

付翔
2013/01/05
0
0
七牛云 RTN:基于 WebRTC 零基础搭建实时音视频平台

引言 近年来,在线教育、狼人杀、在线抓娃娃、线上 KTV 等多人视频互动模式不断涌现,实时音视频通信风头正劲,实时音视频技术 WebRTC 也因此受到了广泛关注。相关数据显示,2017-2021 年期间...

七牛云
07/20
0
0

没有更多内容

加载失败,请刷新页面

加载更多

使用linux将64G的SDCARD格式化为FAT32

一、命令如下: sudo fdisk -lsudo mkfs.vfat /dev/sda -Isudo fdisk /dev/sda Welcome to fdisk (util-linux 2.29.2). Changes will remain in memory only, until you decide to wri......

mbzhong
24分钟前
3
0
深入理解Plasma(四):Plasma Cash

这一系列文章将围绕以太坊的二层扩容框架,介绍其基本运行原理,具体操作细节,安全性讨论以及未来研究方向等。本篇文章主要介绍在 Plasma 框架下的项目 Plasma Cash。 深入理解Plasma(1):...

HiBlock
昨天
1
0
命令参数的三大风格:Posix、BSD、GNU

今天读到命令行中参数的风格有三大类,即Unix/Posix、BSD、GNU。分别有以下特征: Unix/Posix风格,即命令后的参数,可以分组,便必须以连字符开头,如ps -aux。 BSD风格,即命令后的参数,可...

大别阿郎
昨天
2
0
PHP生成图片验证码

PHP生成图片验证码 /** * PHP生成图片验证码 * Class VerifyImage */class VerifyImage{ // 生成随机字串 private $verifyCode; // 图片对象 private $image; /**...

DrChenXX
昨天
1
0
纹理与表面细节添加方法---OpenGL纹理函数

OpenGL线纹理函数 OpenGL表面纹理函数 OpenGL体纹理函数 OpenGL纹理图案的颜色选项 OpenGL纹理映射选项 OpenGL纹理环绕 复制帧缓存中的OpenGL纹理图案 OpenGL纹理坐标数组 OpenGL纹理图案命名...

中国龙-扬科
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部