`
nanjingjiangbiao_T
  • 浏览: 2658691 次
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

最近在做NAT时写的一个双向链表(vc6.0和linux下测试通过)

 
阅读更多
#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内核双向链表简单分析 #### 链表数据结构简介 链表作为一种基本且重要的数据结构,在...通过理解这些基本概念和技术细节,开发者可以更高效地利用双向链表来解决实际问题,并更好地参与到Linux内核开发中。

    连连看vc6.0实现

    在本项目中,"连连看vc6.0实现"是一个基于Microsoft Visual C++ 6.0(简称VC6.0)开发的经典休闲游戏——连连看的实现。它利用了编程技术来构建游戏逻辑,其中涉及到了两个核心概念:双缓冲技术和连连看算法。 **双...

    链表的实现 VC6.0环境 CPP文件 EXE

    在这个VC6.0环境下,我们可以通过C++来实现链表的基本操作。下面将详细介绍链表的实现,包括初始化、插入、删除、求表长、按值查找和按位置查找。 1. **链表的初始化**: 链表的初始化通常涉及创建一个空的链表,...

    整理的linux中的双向链表

    本文将深入探讨Linux中双向链表的概念、其C语言实现以及如何通过`testList.c`、`libList.h`和`testList.h`这三个文件进行实践。 双向链表与单链表不同,它在每个节点上都维护了两个指针,一个指向前一个节点,另一...

    双向链表双向链表双向链表

    与单链表相比,双向链表的主要特点是每个节点不仅包含指向下一个节点的指针,还包含一个指向前一个节点的指针。这种设计使得双向链表在数据操作上具有更高的灵活性,比如可以方便地进行前向和后向遍历。 在双向链表...

    VC6.0链表做的电话簿管理

    总的来说,"VC6.0链表做的电话簿管理"项目是一个很好的学习平台,它结合了基本数据结构(链表)、面向对象编程以及用户界面设计等多个方面。对于初学者来说,通过这个项目,不仅可以掌握链表的使用,还能了解到如何...

    链表有序合并(vc6.0开发)

    本实验“链表有序合并”主要探讨如何在VC6.0环境下,对两个无序链表进行排序和合并,从而得到一个有序的链表。 首先,我们需要了解链表的基本操作,包括创建链表、插入节点、删除节点以及遍历链表。在VC6.0中,我们...

    vc6.0简单运算器

    在本项目中,“vc6.0简单运算器”是一个基于Visual C++ 6.0(简称VC6.0)开发的简易计算器程序。这个计算器具备基本的数学运算功能,可以帮助用户进行加、减、乘、除等计算。下面将详细讨论涉及到的知识点。 1. **...

    Linux内核链表测试

    在"Linux内核链表测试"这个主题中,我们将深入探讨如何在用户态下移植Linux内核链表到VC6.0编译环境中进行测试。首先,我们需要了解Linux内核链表的基本结构和操作,然后讨论用户态移植的过程,最后,通过分析给定的...

    贪吃蛇(vc6.0)

    在Windows开发环境中,Visual C++ 6.0(简称VC6.0)是一款广泛使用的C++集成开发环境,它提供了强大的编程工具和功能,可以用于开发各种应用程序,包括游戏。本篇文章将深入探讨如何使用VC6.0实现一个单文档的贪吃蛇...

    双向链表双向链表

    总的来说,双向链表是数据结构中的一个重要组成部分,它提供了一种灵活的方式来存储和操作序列数据,尤其是在需要高效前后移动和操作的场景下。掌握双向链表的原理和操作方法对于理解和解决问题至关重要,也是成为一...

    支持类模版的C++双向链表

    在C++编程中,双向链表是一种非常重要的数据结构,它允许在列表的任一位置进行插入和删除操作,而不必像数组那样依赖于索引。在这个“支持类模版的C++双向链表”中,我们将探讨如何利用C++的模板特性来实现一个灵活...

    五子棋MFC VC6.0

    本项目“五子棋MFC VC6.0”是利用VC6.0和MFC技术开发的一个五子棋游戏,特别引入了智能人机对战功能,使得游戏更具挑战性。 五子棋是一种古老的双人棋类游戏,双方交替在棋盘上放置棋子,目标是首先形成连续的五个...

    操作系统课设-线程安全的双向链表

    在Windows系统中,如VC6.0环境,我们可以使用互斥量(Mutex)、临界区(Critical Section)或信号量(Semaphore)等机制来确保同一时间只有一个线程能修改链表。 在实现线程安全的双向链表时,以下是一些关键点: ...

    推箱子vc6.0源代码

    它的基本目标是通过在二维格子状的地图上移动一个可以推动箱子的玩家角色,将所有箱子推到指定的目标位置。这个游戏需要玩家运用策略和空间思维能力来解决各个关卡。 在“推箱子vc6.0源代码”中,我们讨论的是使用...

    VC6.0线程池,参考别人代码实现

    在VC6.0中,可以通过`_beginthreadex`函数创建线程,该函数返回一个线程ID,便于后续管理和同步。 2. **任务队列**:线程池需要一个队列来存储待处理的任务。任务通常以函数指针或类成员函数的形式存在,通过结构体...

    VC6.0推箱子游戏源码(编译通过)

    在这个名为“VC6.0推箱子游戏源码(编译通过)”的资源中,我们可以深入学习如何在微软的Visual C++ 6.0(简称VC6.0)环境中开发此类游戏。 1. **VC6.0环境**:VC6.0是微软公司发布的一款集成开发环境,主要用于C/C++...

    一个简单双向链表C实现

    构建了双向链表,实现了 1.int getlistlen(node *head); 根据表头计算链表长度。 2.int displist(node *head) 根据表头从头显示所有元素。 3.int displistfromtail(node *tail) ...开发环境VC6.0下通过。

    VC++6.0 动态链表源程序示例

    通过这个“VC++6.0 动态链表源程序示例”,你可以学习如何在实际编程中实现和管理动态链表,这对于理解和处理复杂数据结构的程序设计至关重要。同时,这也有助于你在后续的学习中更好地理解其他高级数据结构,如双向...

Global site tag (gtag.js) - Google Analytics