建立一个链式结构便于存储用户信息,以便今后处理登录和未登录的信息。首先我们建立一个用户信息的结构:
///客户端信息结构 typedef struct _client *lp_client;///客户端信息指针结构 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就是用于链接的,为了更好的操作这个链接,我们需要建立两个变量来便于操作和处理,这两个变量是根节点和末节点变量。
///客户信息列表根节点 lp_client rootItem = NULL;///客户信息列表末节点 lp_client lastItem = NULL;
下面提供一下整个代码,包含查询、增加、删除等操作。
UDPList.h
#pragma once#include "targetver.h"///信息结构的指针型 typedef struct _message *lp_message;///信息结构 typedef struct _message{ union { struct { char buff[1030]; }; struct { char cmd[6]; char rt_code[32]; char data[992]; }; }; SOCKADDR_IN addr;};///客户端信息结构 typedef struct _client *lp_client;///客户端信息指针结构 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; //链表下一个};///根据用户名称得到用户信息节点 lp_client IndexOf(char* appCode, char * userName);///根据用户名称得到用户信息节点 lp_client IndexOf(char* appCode, char * userName, char * machineCode);///根据运行编码得到用户信息节点 lp_client IndexOf(char * runtimeCode);///添加一个客户端信息 lp_client addClient(char* userName, char* userPassword, char* appCode, char* machineCode);///添加一个客户端信息 void addClient(lp_client client);///一个客户端登录系统 lp_client regClient(char * userName, char * userPassword, char * appCode, struct in_addr addr, u_short port);///一个客户端登录系统 lp_client regClient(char * userName, char * userPassword, char * appCode, char * machineCode, struct in_addr addr, u_short port);///根据用户名称删除用户信息节点 void removeClient(char* appCode, char * userName);///从文件缓存中提取客户端列表 void loadFromFile(char* filename);///将客户端列表写入缓存文件 void saveToFile(char* filename);
下面是UDPList.cpp
#include "stdafx.h"#include "UDPList.h"///客户信息列表根节点 lp_client rootItem = NULL;///客户信息列表末节点 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]);}///根据用户名称得到用户信息节点 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;}///根据用户名称得到用户信息节点 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;}///根据运行编码得到用户信息节点 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;}///一个客户端登录系统 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;}///一个客户端登录系统 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;}///根据用户名称删除用户信息节点 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; }}///从文件缓存中提取客户端列表 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);}///将客户端列表写入缓存文件 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);}///添加一个客户端信息 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;}///添加一个客户端信息 void addClient(lp_client client){ if (rootItem == NULL)rootItem = client; else lastItem->next = client; lastItem = client;}
同时函数还实现了文件缓存功能,通过SaveToFile和LoadFromFile来实现。