建立一个链式结构便于存储用户信息,以便今后处理登录和未登录的信息。首先我们建立一个用户信息的结构:
/// <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来实现。