反向代理服务器面对用户请求和后端服务器响应,需要将两者联系起来,于是就涉及到socket关联查询了。

  代理服务器处理用户的请求和后端服务器的响应,并且这两方的请求和响应是相互对应的,因此对于代理接收到服务器的响应该如何找到这个响应对应的用户请求;甚至代理在处理一个socket描述符时,如何确定是发送给用户的响应,还是发给后端服务器的请求。

  我提出来的方案是

socket关联查询整体模型如下图所示:

socket关联查询整体模型

为了建立代理对客户端的请求与后端服务器的响应,建立一个映射哈希表。socket关联查询详细模型如图所示:

socket关联查询详细模型

1、用户请求连接时,先加入到epoll中,建立连接后,并且有请求任务到来时,将该任务加入到线程池,即对fdc进行操作;

2、当用户实际上是与后端服务器交互时,代理需要与后端服务器建立连接,这时需要创建一个fds,这时将以fdc和fds为关键字加入到哈希表中;

3、当后端服务器有响应时,加入到epoll中;当有响应任务时,加入到线程池处理响应任务;

4、当代理需要将后端服务器的响应再次响应给用户时,查询匹配哈希表,即可找到fds与fdc的映射,这样就能正确的对该请求的用户进行响应。

对于哈希表的设计,下面又给出实验代码:当然具体实现还待将代理的功能实现在将这个整合。代码如下:

#include    <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h> #define HASHSIZE 997
#define C_S 2
#define S_C 1
typedef struct _Node Node;
typedef struct _Hash Hash;
struct _Node{
int value;
int fds;
int fdc;
/* conn_staut=1表示ref_fd=fds,代理把数据发送给fdc
* conn_staut=2表示ref_fd=fdc,代理把数据发送给fds */
int conn_staut;
Node *next;
}; struct _Hash{
int key;
Node *next;
}; static Hash hash[HASHSIZE]; /* 哈希函数 */
int hash_fun(int ref_fd)
{
return ref_fd % HASHSIZE;
} /* 初始化哈希表 */
void hash_init()
{
int i = ;
for(i = ; i < HASHSIZE; i++)
{
hash[i].key = ;
hash[i].next = NULL;
}
} /* 哈希节点的匹配 */
Node*
hash_fdmate(int ref_fd)
{
int hash_val;
hash_val = hash_fun(ref_fd); if(hash[hash_val].next == NULL)
return NULL; Node *p = hash[hash_val].next;
for(; p->next == NULL; p = p->next)
{
if(ref_fd == p->fds || ref_fd == p->fdc)
{
return p;
}
}
return NULL;
} /* 哈希节点的插入 */
Node*
hash_insert(int fdc, int fds)
{
Node *node_c = (Node *)malloc(sizeof(Node));
Node *node_s = (Node *)malloc(sizeof(Node));
if(node_c == NULL || node_s == NULL)
return NULL;
bzero(node_c, sizeof(Node));
bzero(node_s, sizeof(Node)); node_c->fds = fds;
node_c->fdc = fdc;
node_c->conn_staut = C_S; node_s->fds = fds;
node_s->fdc = fdc;
node_s->conn_staut = S_C; /* 先以fdc加入到哈希表中 */
int hash_val;
hash_val = hash_fun(fdc);
if(hash[hash_val].next == NULL)
{
hash[hash_val].next = node_c;
}else
{
node_c->next = hash[hash_val].next;
hash[hash_val].next = node_c;
} /* 先以fds加入到哈希表中 */
hash_val = hash_fun(fds);
if(hash[hash_val].next == NULL)
{
hash[hash_val].next = node_s;
}else
{
node_s->next = hash[hash_val].next;
hash[hash_val].next = node_s;
}
return node_c;
} /* 销毁整哈希表*/
void
hash_destroy()
{ } /* 删除哈希中的某个节点 */
Node*
hash_delete(int ref_fd)
{ } #if 1
int main(void)
{
int fdc = ;
int fds = ; hash_init();
hash_insert(fdc, fds); Node *np = hash_fdmate();
if(np == NULL)
{
printf("no find!\n");
return ;
}
printf("%d\n", np->conn_staut);
return ;
} #endif

socket关联查询的更多相关文章

  1. JDBC MySQL 多表关联查询查询

    public static void main(String[] args) throws Exception{ Class.forName("com.mysql.jdbc.Driver&q ...

  2. MYSQL基础操作之数据约束与关联查询

    一.MYSQL约束 1.默认值约束,当字段没有插入值的时候,mysql自动给该字段分配默认值. 默认值的字段允许为空. 对默认值字段也可以插入null. CREATE TABLE STUDENT( I ...

  3. C#代码中实现两个表(DataTable)的关联查询(JOIN)

    之前通常都是使用SQL直接从数据库中取出表1和表2关联查询后的数据,只需要用一个JOIN就可以了,非常方便.近日遇到一种情况,两个表中的数据已经取到代码中,需要在代码中将这两个表关联起来,并得到它们横 ...

  4. Mybatis关联查询和数据库不一致问题分析与解决

    Mybatis关联查询和数据库不一致问题分析与解决 本文的前提是,确定sql语句没有问题,确定在数据库中使用sql和项目中结果不一致. 在使用SpringMVC+Mybatis做多表关联时候,发现也不 ...

  5. Mysql多表表关联查询 inner Join left join right join

    Mysql多表表关联查询 inner Join left join right join

  6. YII2-数据库数据查询方法,关联查询with, joinWith区别和分页

    一.ActiveRecord 活动记录 1.with关联查询 例如,查询评论 $post = Post::find()->with('comments'); 等价于以下结果集 SELECT * ...

  7. Mybatis高级查询之关联查询

    learn from:http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html#Result_Maps 关联查询 准备 关联结果查询(一对一) resul ...

  8. Spring+MyBatis框架中sql语句的书写,数据集的传递以及多表关联查询

    在很多Java EE项目中,Spring+MyBatis框架经常被用到,项目搭建在这里不再赘述,现在要将的是如何在项目中书写,增删改查的语句,如何操作数据库,以及后台如何获取数据,如何进行关联查询,以 ...

  9. [NHibernate]一对多关系(关联查询)

    目录 写在前面 文档与系列文章 一对多查询 总结 写在前面 上篇文章介绍了nhibernate的一对多关系如何配置,以及级联删除,级联添加数据的内容.这篇文章我们将学习nhibernate中的一对多关 ...

随机推荐

  1. Java创建树形结构算法实例

    在JavaWeb的相关开发中经常会涉及到多级菜单的展示,为了方便菜单的管理需要使用数据库进行支持,本例采用相关算法讲数据库中的条形记录进行相关组装和排序讲菜单组装成树形结构. 首先是需要的JavaBe ...

  2. Nginx快速入门菜鸟笔记

    Nginx快速入门-菜鸟笔记   1.编译安装nginx 编译安装nginx 必须先安装pcre库. (1)uname -a 确定环境 Linux localhost.localdomain 2.6. ...

  3. Javascript模式(第二章基本技巧)------读书笔记

    本章主要帮助大家写出高质量的JS代码的方法,模式和习惯,例如:避免使用全局变量,使用单个的var变量声明,缓存for循环的长度变量length等 一.尽量避免使用全局变量 1 每一个js环境都有一个全 ...

  4. 显示intent和隐示intent有什么区别

    显式Intent定义:对于明确指出了目标组件名称的Intent,我们称之为显式Intent. 隐式Intent定义:对于没有明确指出目标组件名称的Intent,则称之为隐式Intent. 说明:And ...

  5. matlab global 不能传向量/矩阵

    matlab global 不能传向量/矩阵 只能传1个数值 而函数变量可以传向量/矩阵

  6. JAVA 取得当前目录的路径/Servlet/class/文件路径/web路径/url地址

    在写java程序时不可避免要获取文件的路径...总结一下,遗漏的随时补上 1.可以在servlet的init方法里 String path = getServletContext().getRealP ...

  7. Bar菜单

    简介 BarButtonItem:元素(按钮.子菜单.标签.编辑器等) this.barButtonItem3 = new DevExpress.XtraBars.BarButtonItem(); B ...

  8. openssl生成ssl证书

    openssl生成ssl证书 x509证书一般会用到三类文,key,csr,crt. Key 是私用密钥openssl格,通常是rsa算法. Csr 是证书请求文件,用于申请证书.在制作csr文件的时 ...

  9. IE报错:模块"scrrun.dll"已加载,但对DllRegisterServer的调用失败,错误代码为0x80004005

    在我的win10系统上打开某内部网页登录的时候弹出'模块"scrrun.dll"已加载,但对DllRegisterServer的调用失败,错误代码为0x80004005'报错信息, ...

  10. Retina Display and Eclipse Mac视网膜屏和Eclipse

    I have a Retina Display and Eclipse looks blurry. How can I fix it? You need to tell Mac OS that Ecl ...