#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_PEER_LEN 64
typedef unsigned long u64_t;
typedef unsigned int u32_t;
typedef unsigned short u16_t;
typedef unsigned char u8_t;
typedef signed char s8_t;
typedef u32_t ip_addr_t;
typedef u16_t port_t;
/* gnat header */
typedef struct gnat_hdr
{
ip_addr_t lcl_addr; // local address with 32 bytes
ip_addr_t ref_addr; // public address with 32 bytes
ip_addr_t rel_addr; // relay address with 32 bytes
port_t lcl_port; // local port number with 16 bytes
port_t ref_port; // public port number with 16 bytes
port_t rel_port; // relay port number with 16 bytes
u16_t type; // type of action
u16_t id_len; // length of actual peer id
u8_t peer_id[MAX_PEER_LEN]; // peer_id with 16 bytes defined in peer_length
}gnat_hdr_t;
typedef struct peer_table{
gnat_hdr_t *peer;
struct peer_table *next;
} peer_table;
/* peer list */
typedef struct peer_list
{
struct peer_table *first;
struct peer_table *last;
struct peer_table *head;
} peer_list_t;
peer_list_t pplist;
peer_table *gnat_add_peer(peer_list_t *plist, gnat_hdr_t *peer)
{
peer_table *ppeer;
ppeer = (peer_table *)calloc(1, sizeof(peer_table));
ppeer->peer = peer;
if ( ppeer == NULL )
return(NULL);
if(plist->first) {
ppeer->next = plist->first->next;
plist->first->next = ppeer;
}else{
ppeer->next = plist->head;
plist->head = ppeer;
}
return ppeer;
}
static peer_table *gnat_search_peer(peer_list_t *plist, u8_t peer_id[]) {
peer_table *pp;
pp = plist->head;
while(pp) {
if (!strcmp((char *)pp->peer->peer_id, (const char *)peer_id)) {
break;
}
pp = pp->next;
}
return pp;
}
static u32_t gnat_destroy_peer(peer_list_t *plist, peer_table *peer)
{
peer_table **pp;
pp = &plist->head;
while (*pp) {
if ( *pp == peer )
break;
pp = &((*pp)->next);
}
if ( *pp == peer) {
*pp = peer->next;
if (plist->first == peer)
plist->first = NULL;
if (plist->last == peer )
plist->last = NULL;
free(peer);
return (0);
} else {
return -1;
}
return (0);
}
int main(void)
{
gnat_hdr_t msg;
u8_t str[32] = "peerA";
peer_table *pp;
msg.id_len = 4;
msg.lcl_addr = 0;
msg.lcl_port = 0;
memcpy(msg.peer_id, str, 6);
msg.ref_addr = 0;
msg.ref_port =0;
msg.rel_addr = 0;
msg.rel_port = 0;
msg.type = 1;
gnat_add_peer(&pplist, &msg);
pp = gnat_search_peer(&pplist, str);
printf("%d\n", pp->peer->id_len);
gnat_destroy_peer(&pplist, pp);
if((pp = gnat_search_peer(&pplist, str)) == NULL)
printf("Delete sucess!\n");
return (0);
}
分享到:
相关推荐
### Linux内核双向链表简单分析 #### 链表数据结构简介 链表作为一种基本且重要的数据结构,在...通过理解这些基本概念和技术细节,开发者可以更高效地利用双向链表来解决实际问题,并更好地参与到Linux内核开发中。
在本项目中,"连连看vc6.0实现"是一个基于Microsoft Visual C++ 6.0(简称VC6.0)开发的经典休闲游戏——连连看的实现。它利用了编程技术来构建游戏逻辑,其中涉及到了两个核心概念:双缓冲技术和连连看算法。 **双...
在这个VC6.0环境下,我们可以通过C++来实现链表的基本操作。下面将详细介绍链表的实现,包括初始化、插入、删除、求表长、按值查找和按位置查找。 1. **链表的初始化**: 链表的初始化通常涉及创建一个空的链表,...
本文将深入探讨Linux中双向链表的概念、其C语言实现以及如何通过`testList.c`、`libList.h`和`testList.h`这三个文件进行实践。 双向链表与单链表不同,它在每个节点上都维护了两个指针,一个指向前一个节点,另一...
总的来说,"VC6.0链表做的电话簿管理"项目是一个很好的学习平台,它结合了基本数据结构(链表)、面向对象编程以及用户界面设计等多个方面。对于初学者来说,通过这个项目,不仅可以掌握链表的使用,还能了解到如何...
本实验“链表有序合并”主要探讨如何在VC6.0环境下,对两个无序链表进行排序和合并,从而得到一个有序的链表。 首先,我们需要了解链表的基本操作,包括创建链表、插入节点、删除节点以及遍历链表。在VC6.0中,我们...
在本项目中,“vc6.0简单运算器”是一个基于Visual C++ 6.0(简称VC6.0)开发的简易计算器程序。这个计算器具备基本的数学运算功能,可以帮助用户进行加、减、乘、除等计算。下面将详细讨论涉及到的知识点。 1. **...
在"Linux内核链表测试"这个主题中,我们将深入探讨如何在用户态下移植Linux内核链表到VC6.0编译环境中进行测试。首先,我们需要了解Linux内核链表的基本结构和操作,然后讨论用户态移植的过程,最后,通过分析给定的...
在Windows开发环境中,Visual C++ 6.0(简称VC6.0)是一款广泛使用的C++集成开发环境,它提供了强大的编程工具和功能,可以用于开发各种应用程序,包括游戏。本篇文章将深入探讨如何使用VC6.0实现一个单文档的贪吃蛇...
在C++编程中,双向链表是一种非常重要的数据结构,它允许在列表的任一位置进行插入和删除操作,而不必像数组那样依赖于索引。在这个“支持类模版的C++双向链表”中,我们将探讨如何利用C++的模板特性来实现一个灵活...
本项目“五子棋MFC VC6.0”是利用VC6.0和MFC技术开发的一个五子棋游戏,特别引入了智能人机对战功能,使得游戏更具挑战性。 五子棋是一种古老的双人棋类游戏,双方交替在棋盘上放置棋子,目标是首先形成连续的五个...
在Windows系统中,如VC6.0环境,我们可以使用互斥量(Mutex)、临界区(Critical Section)或信号量(Semaphore)等机制来确保同一时间只有一个线程能修改链表。 在实现线程安全的双向链表时,以下是一些关键点: ...
它的基本目标是通过在二维格子状的地图上移动一个可以推动箱子的玩家角色,将所有箱子推到指定的目标位置。这个游戏需要玩家运用策略和空间思维能力来解决各个关卡。 在“推箱子vc6.0源代码”中,我们讨论的是使用...
在VC6.0中,可以通过`_beginthreadex`函数创建线程,该函数返回一个线程ID,便于后续管理和同步。 2. **任务队列**:线程池需要一个队列来存储待处理的任务。任务通常以函数指针或类成员函数的形式存在,通过结构体...
在这个名为“VC6.0推箱子游戏源码(编译通过)”的资源中,我们可以深入学习如何在微软的Visual C++ 6.0(简称VC6.0)环境中开发此类游戏。 1. **VC6.0环境**:VC6.0是微软公司发布的一款集成开发环境,主要用于C/C++...
构建了双向链表,实现了 1.int getlistlen(node *head); 根据表头计算链表长度。 2.int displist(node *head) 根据表头从头显示所有元素。 3.int displistfromtail(node *tail) ...开发环境VC6.0下通过。
通过这个“VC++6.0 动态链表源程序示例”,你可以学习如何在实际编程中实现和管理动态链表,这对于理解和处理复杂数据结构的程序设计至关重要。同时,这也有助于你在后续的学习中更好地理解其他高级数据结构,如双向...
在Java中,我们可以创建一个表示链表节点的类,通常称为`Node`,包含数据字段和指向下一个节点的引用。然后,创建一个`LinkedList`类,包含头节点并提供所需操作的方法。例如,要在头部添加节点,可以创建新节点并将...
“贪吃蛇游戏”是一个经典的计算机游戏,它的实现通常基于事件驱动编程,通过监听键盘输入改变蛇的移动方向,并利用二维数组或链表来表示游戏地图和蛇的身体。此外,理解游戏逻辑,如蛇的移动规则、食物生成以及碰撞...