以下基于linux内核 2.4.0 源码(转载请注明出处)
网络通信过程中,服务器必然提供监听socket响应客户端连接请求,也必然提供连接socket与客户端进行交互。一台主机上有不止一个的socket服务器,如ftp、telnet服务器等,他们初始都处于监听状态,等待连接请求的到来。linux中为了管理这两类socket提供了两个哈希链表:tcp_listening_hash和tcp_ehash,下面主要分析下监听哈希表,顺带说下连接hash表。
一、链表定义
在include/net/tcp.h中定义了tcp_hashinfo结构,包含了tcp协议所涉及到的一些哈希表信息,这两个哈希表以tcp_hashinfo的成员形式出现,如下所示:
extern struct tcp_hashinfo {
/* 结构成员用于tcp状态迁移图中的相关状态:
* TCP_ESTABLISHED <= sk->state < TCP_CLOSE
* 前半部份用于非超时状态,后半部份仅用于超时状态
*/
struct tcp_ehash_bucket *__tcp_ehash;
/* tcp的绑定哈希表,用于快速bind/connect*/
struct tcp_bind_hashbucket *__tcp_bhash;
int __tcp_bhash_size;
int __tcp_ehash_size;
/* 所有在监听状态的socket都存放在下面的哈希表中,其中键key为本地监听端口*/
struct sock *__tcp_listening_hash[TCP_LHTABLE_SIZE];
/*下面的成员缓冲区对齐*/
rwlock_t __tcp_lhash_lock /*监听哈希表访问锁*/
__attribute__((__aligned__(SMP_CACHE_BYTES)));
atomic_t __tcp_lhash_users;
wait_queue_head_t __tcp_lhash_wait;
/*上述三个成员主要用于用户通过/proc/ne获取监听套接字(间接访问监听哈希表时)信息时异步处理*/
spinlock_t __tcp_portalloc_lock;
} tcp_hashinfo;
接下来定义了一些宏以简化引用:
#define tcp_ehash (tcp_hashinfo.__tcp_ehash) /*连接哈希链表*/
#define tcp_bhash (tcp_hashinfo.__tcp_bhash) /*地址bind哈希链表*/
#define tcp_ehash_size (tcp_hashinfo.__tcp_ehash_size) /*连接哈希链表长度