文档章节

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

jamesvon
 jamesvon
发布于 2017/07/22 15:52
字数 1247
阅读 18
收藏 0
点赞 0
评论 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 ⋅ 0

阿里云上线视频云剪辑 快速产出PGC短视频不再是问题!

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

音染 ⋅ 2017/07/21 ⋅ 0

OpenVPN中TAP-win32d的net30问题

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

晨曦之光 ⋅ 2012/04/10 ⋅ 0

有了WCF,Socket是否已人老珠黄?

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

付翔 ⋅ 2013/01/05 ⋅ 0

Sopcast的网友评论

SopCast是一个简单易用的软件(非开源),使用他可以在互联网上免费播出音频、视频节目,也可以通过互联网观看节目。SopCast采用P2P(Peer- to-Peer)技术传输数据,非常高效。使用SopCast每个...

红薯 ⋅ 2009/12/11 ⋅ 4

P2P流媒体直播系统--Sopcast

SopCast是一个简单易用的软件(非开源),使用他可以在互联网上免费播出音频、视频节目,也可以通过互联网观看节目。SopCast采用P2P(Peer- to-Peer)技术传输数据,非常高效。使用SopCast每个...

匿名 ⋅ 2009/05/12 ⋅ 4

利用WCF的P2P共享剪贴板上的数据

WCF与P2P WCF是用来实现数据通信的,这篇文章中。我将带领大家进入WCF的P2P的世界。通过一个实例,说明WCF中使用P2P。 首先让我们了解一下什么是P2P。详细见:P2P。这里根据我的理解,结合W...

晨曦之光 ⋅ 2012/03/09 ⋅ 0

利用WCF的P2P共享剪贴板上的数据

WCF与P2P WCF是用来实现数据通信的,这篇文章中。我将带领大家进入WCF的P2P的世界。通过一个实例,说明WCF中使用P2P。 首先让我们了解一下什么是P2P。详细见:P2P。这里根据我的理解,结合W...

王二狗子11 ⋅ 01/01 ⋅ 0

释放技术的想象 解码腾讯云软件架构与应用

欢迎大家前往腾讯云社区,获取更多腾讯海量技术实践干货哦~ 关于腾讯 你可能玩过“王者荣耀” 你可能用过“微信”和它的“小程序” 你可能看过“腾讯视频”并且曾为之付费 你可能已经是多年的...

⋅ 2017/12/18 ⋅ 0

视频会议软件VMukti 1.1.3.1版本发布

VMukti 是基于web/PSDTN的P2P呼叫中心和视频会议程序。 VMukti 1.1.3.1发布,新版本包括如下功能: 播放记录文件播放记录文件; P2P富媒体内容管理平台; 第三方模块; P2P 视频/音频; P2P ...

老枪 ⋅ 2009/04/02 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Mahout基于内存的DataMode 推荐引擎Demo2

Mahout基于内存的DataMode 推荐引擎Demo2 //注释的部分是基于文件也可以理解为基于日志文件的, //DataModel 可以有很多种,实现abstractDataMode的子类,原则上都可以作为数据源,个人觉得,...

xiaomin0322 ⋅ 7分钟前 ⋅ 0

Docker部署Tomcat及Web应用

一、在线下载docker yum install -y epel-releaseyum install docker-io # 安装dockerchkconfig docker on # 加入开机启动service docker start # 启动docker服务 1 ...

Jeam_ ⋅ 7分钟前 ⋅ 0

研发运营一体化能力成熟度模型

研发运营一体化是指在 IT 软件及相关服务的研发及交付过程中,将应用的需求、开发、测试、部 署和运营统一起来,基于整个组织的协作和应用架构的优化,实现敏捷开发、持续交付和应用运营的无...

stars永恒 ⋅ 12分钟前 ⋅ 0

jQuery缩小放大触发事件

jquery的resize()方法使用 <html> <head> <script type="text/javascript" src="/jquery/jquery.js"></script> <script type="text/javascript"> var i = 0; $(document).ready(function(){ ......

RobertZou ⋅ 13分钟前 ⋅ 0

eclipse python 搭建

https://jingyan.baidu.com/article/9113f81b68ebce2b3214c7e0.html https://www.cnblogs.com/ZhangRuoXu/p/6397756.html https://blog.csdn.net/zhangphil/article/details/78962159 字符集......

之渊 ⋅ 13分钟前 ⋅ 0

weex,react native,flutter

weex: 一次编写,处处运行 RN: 学一次,到处写(针对安卓,IOS平台特性 各自写,会有很大一部分是一样的代码) 这些方案是否真正的解决了跨平台问题呢?从目前的状况来看,很显然是没有的,因...

东东笔记 ⋅ 19分钟前 ⋅ 0

Spring Cloud微服务分布式云架构-集成项目

Spring Cloud集成项目有很多,下面我们列举一下和Spring Cloud相关的优秀项目,我们的企业架构中用到了很多的优秀项目,说白了,也是站在巨人的肩膀上去整合的。在学习Spring Cloud之前大家必...

明理萝 ⋅ 24分钟前 ⋅ 1

SpringMVC图片上传问题解决

当我们上传图片时一直发现: MultipartFile file = null; if (request instanceof MultipartHttpServletRequest) 匹配不上, 解决方案: 在前端xml加入如下配置代码即可 <!-- 图片上传bean --...

泉天下 ⋅ 26分钟前 ⋅ 0

Spring表达式语言(SpEL)

1、SpEL引用 Spring EL在bean创建时执行其中的表达式。此外,所有的Spring表达式都可以通过XML或注解的方式实现。下面将使用Spring表达式语言(SpEL),注入字符串,整数,Bean到属性。 SpEL的...

霍淇滨 ⋅ 42分钟前 ⋅ 0

Gradle使用阿里云镜像

gradle 生命周期中有一个初始化( Initialization )的过程,这个过程运行在 build script 之前,我们可以在这个地方做一点系统全局的设置,如配置仓库地址。 你可以在以下几个位置实现仓库地址...

明MikeWoo ⋅ 51分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部