反向代理服务器面对用户请求和后端服务器响应,需要将两者联系起来,于是就涉及到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. mac ssh localhost

    转自:http://blog.csdn.net/cwj649956781/article/details/37913637 mac 无法ssh localhost,错误提示:bash: /usr/lo ...

  2. day1作业--登录入口

    作业概述: 编写一个登录入口,实现如下功能: (1)输入用户名和密码 (2)认证成功后显示欢迎信息 (3)输错三次后锁定 流程图: readme: 1.程序配置文件: 黑名单文件blacklist.t ...

  3. ARC中KVO开发注意

    1 在ARC 中 KVO开发 添加监听和去掉监听必需 一一匹配,不要有过的去掉监听否则会有可能导致对象无法释放. 例如,在一个viewcontroller中添加webview 并监听webview的c ...

  4. Java 技术文章摘录

    sokcet 编程实例 android bundle类 Android -- Looper.prepare()和Looper.loop() —深入版 Java NIO系列教程 XML操作 Androi ...

  5. 针对WebService服务,客户端调用时报序列化的最大项数maxItemsInObjectGraph超过65536问题

    今天在使用webservice服务时候,报异常"The InnerException message was 'Maximum number of items that can be ser ...

  6. Oracle Merge备忘示例

    Oracle的merge语法非常实用,用于Insert.Update判断情况.以下是自己书写的一个示例,以免时间长了语法形式忘记了. MERGE INTO T_FR_GUOSZX T USING (S ...

  7. [Linux编程]__read_mostly变量含义

    1.定义 __read_mostly原语将定义的变量为存放在.data.read_mostly段中,原型在include/asm/cache.h 中定义: #define __read_mostly ...

  8. oracle11g dataguard 完全手册

    一.前言: 网络上关于dataguard的配置文章很多,但是很多打着oracle11g的文章实际都是只能在9 10 上运行,比如FAL_CLIENT在11g中已经废弃,但是现在网络上的文章都是没有标注 ...

  9. 如何通过JavaScript构建Asp.net服务端控件

    摘要 虽然ASP.NET的服务器控件一直被大家所诟病,但是用户控件(ACSX)在某些场景下还是非常有用的. 在一些极特珠的情况下,我们会使用JavaScript动态的构建页面中的控件,但假设遇到了我要 ...

  10. (Skill)238. Product of Array Except Self

    Given an array of n integers where n > 1, nums, return an array output such that output[i] is equ ...