我在打开src文件夹时,大概浏览了一遍文件后,我突然发现了List.cpp和List.h文件。我一直在想,什么地方会用到List?在前一篇转载的文章中,作者在介绍Audience类的时候提到了一句话,"Server 将所有Client(Audience)的连接信息组织成一个单向链表,每个Client对应链表中的一项,该项包含该Client的地址结构(sockaddr)以及实现与该Client对应的监控线程的对象(我们称它为监控对象),所有与此Client相关的听者对象和说者对象都是由该监控线程生成的。"。这里,有必要对这两个文件进行一些分析以作为后期更加深入理解的基础。
首先,阅读List.h源文件:
#ifndef Iperf_LIST_H
#define Iperf_LIST_H
#include "headers.h"
#include "Audience.hpp"
/*
* List handling utilities to replace STD vector
*/
struct Iperf_ListEntry;
/*
* A List entry that consists of a sockaddr
* a pointer to the Audience that sockaddr is
* associated with and a pointer to the next
* entry
*/
struct Iperf_ListEntry {
iperf_sockaddr data;
Audience* holder;
Iperf_ListEntry *next;
};
/*
* Functions to modify or search the List
*/
void Iperf_pushback ( Iperf_ListEntry *add, Iperf_ListEntry **root );
void Iperf_delete ( iperf_sockaddr *del, Iperf_ListEntry **root );
void Iperf_destroy ( Iperf_ListEntry **root );
Iperf_ListEntry* Iperf_present ( iperf_sockaddr *find, Iperf_ListEntry *root );
Iperf_ListEntry* Iperf_hostpresent ( iperf_sockaddr *find, Iperf_ListEntry *root );
#endif
在头文件中,有一个很重要的结构体:
struct Iperf_ListEntry {
iperf_sockaddr data;
Audience* holder;
Iperf_ListEntry *next;
};
在这个结构体中,有三个成员变量:
第一个 iperf_sockaddr data; ---->其指代的是套接字地址;
第二个 Audience* holder; ---->其指代的是Audience指针;
第三个 Iperf_ListEntry *next; ----->其指代的是此结构体的指针,这是典型的链表struct。
在本文件中,还有几个成员函数,其实现的功能基本同普通链表操作差不多,但这里还是提出来以加深印象:
(结合List.c文件内容)
A、Iperf_pushback函数:将Iperf_ListEntry结构体指针压入链表
/*
* Add Entry add to the List
*/
void Iperf_pushback ( Iperf_ListEntry *add, Iperf_ListEntry **root ) {
add->next = *root;
*root = add;
}
B、Iperf_present函数:定位find指针指向的Iperf_ListEntry结构体(套接字地址相同)
/*
* Check if the exact Entry find is present
*/
Iperf_ListEntry* Iperf_present ( iperf_sockaddr *find, Iperf_ListEntry *root ) {
Iperf_ListEntry *itr = root;
while ( itr != NULL ) {
if ( SocketAddr::are_Equal( (sockaddr*)itr, (sockaddr*)find ) ) {
return itr;
}
itr = itr->next;
}
return NULL;
}
C、Iperf_delete 函数:先用Iperf_present定位所删除的结构体,然后再进行删除操作
/*
* Delete Entry del from the List
*/
void Iperf_delete ( iperf_sockaddr *del, Iperf_ListEntry **root ) {
Iperf_ListEntry *temp = Iperf_present( del, *root );
if ( temp != NULL ) {
if ( temp == *root ) {
*root = (*root)->next;
} else {
Iperf_ListEntry *itr = *root;
while ( itr->next != NULL ) {
if ( itr->next == temp ) {
itr->next = itr->next->next;
break;
}
itr = itr->next;
}
}
delete temp;
}
}
D、Iperf_destory函数:销毁(释放)链表空间
/*
* Destroy the List (cleanup function)
*/
void Iperf_destroy ( Iperf_ListEntry **root ) {
Iperf_ListEntry *itr1 = *root, *itr2;
while ( itr1 != NULL ) {
itr2 = itr1->next;
delete itr1;
itr1 = itr2;
}
*root = NULL;
}
E、Iperf_hostpresent函数:定位find指针指向的Iperf_ListEntry结构体(主机地址相同)
/*
* Check if a Entry find is in the List or if any
* Entry exists that has the same host as the
* Entry find
*/
Iperf_ListEntry* Iperf_hostpresent ( iperf_sockaddr *find, Iperf_ListEntry *root ) {
Iperf_ListEntry *itr = root;
while ( itr != NULL ) {
if ( SocketAddr::Hostare_Equal( (sockaddr*)itr, (sockaddr*)find ) ) {
return itr;
}
itr = itr->next;
}
return NULL;
}