diff --git a/README.md b/README.md
index 0c65676..3c23219 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
 # easyProxy
 ![](https://img.shields.io/github/stars/cnlh/easyProxy.svg)   ![](https://img.shields.io/github/forks/cnlh/easyProxy.svg) ![](https://img.shields.io/github/license/cnlh/easyProxy.svg)
 
-easyProxy是一款轻量级、高性能、功能最为强大的**内网穿透**代理服务器。目前支持**tcp、udp流量转发**,可支持任何tcp、udp上层协议(访问内网网站、本地支付接口调试、ssh访问、远程桌面,内网dns解析等等……),此外还**支持内网http代理、内网socks5代理**,可实现在非内网环境下如同使用vpn一样访问内网资源和设备的效果,同时**支持socks5验证,snnapy压缩(节省带宽和流量)、站点保护、加密传输、多路复用、host修改、自定义header**。
+easyProxy是一款轻量级、高性能、功能最为强大的**内网穿透**代理服务器。目前支持**tcp、udp流量转发**,可支持任何tcp、udp上层协议(访问内网网站、本地支付接口调试、ssh访问、远程桌面,内网dns解析等等……),此外还**支持内网http代理、内网socks5代理**,可实现在非内网环境下如同使用vpn一样访问内网资源和设备的效果。
 
 目前市面上提供类似服务的有花生壳、TeamView、GoToMyCloud等等,但要使用第三方的公网服务器就必须为第三方付费,并且这些服务都有各种各样的限制,此外,由于数据包会流经第三方,因此对数据安全也是一大隐患。
 
@@ -38,33 +38,47 @@ easyProxy是一款轻量级、高性能、功能最为强大的**内网穿透**
 - [x] 支持一个服务端,多个客户端模式
 - [x] host修改支持
 - [x] 自定义设置header支持
+- [x] 流量统计
+- [x] 自动义404页面
+- [x] 热更新支持
 
 ## 目录
 
-1. [安装](#安装)
-2. [web管理模式](#web管理模式)(多隧道时推荐)
-3. [tcp隧道模式](#tcp隧道模式)
-4. [udp隧道模式](#udp隧道模式)
-5. [socks5代理模式](#socks5代理模式)
-6. [http代理模式](#http代理模式)
-7. [数据压缩支持](#数据压缩支持)
-8. [站点密码保护](#站点保护)
-9. [加密传输](#加密传输)
-10. [TCP多路复用](#多路复用)
-11. [host修改](#host修改)
-12. [自定义header](#自定义header)
-13. [获取用户真实ip](#获取用户真实ip)
+* [安装](#安装)
+    * [编译安装](#源码安装)
+    * [release安装](#release安装)
+* [web管理](#web管理模式)(多隧道时推荐)
+    * [启动](#启动)
+    * [配置文件说明](#服务端配置文件)
+* 单隧道模式及介绍
+    * [tcp隧道模式](#tcp隧道模式)
+    * [udp隧道模式](#udp隧道模式)
+    * [socks5代理模式](#socks5代理模式)
+    * [http代理模式](#http代理模式)
 
+* [相关功能](#相关功能)
+   * [数据压缩支持](#数据压缩支持)
+   * [站点密码保护](#站点保护)
+   * [加密传输](#加密传输)
+   * [TCP多路复用](#多路复用)
+   * [host修改](#host修改)
+   * [自定义header](#自定义header)
+   * [获取用户真实ip](#获取用户真实ip)
+   * [热更新支持](#热更新支持)
+   * [客户端地址显示](#客户端地址显示)
+   * [自定义404页面](#404页面配置)
+   * [流量统计](#流量统计)
+   * [连接池](#连接池)
 
 ## 安装
 
-1. release安装
+### release安装
 > https://github.com/cnlh/easyProxy/releases
 
 下载对应的系统版本即可,服务端和客户端是单独的,go语言开发,无需任何第三方依赖
 
-2. 源码安装
-- 安装源码
+### 源码安装
+- 安装源码(另有snappy、beego包)
 > go get github.com/cnlh/easyProxy
 - 编译
 > go build cmd/server/proxy_server.go
@@ -89,35 +103,7 @@ tcpport  | 服务端客户端通信端口
 
 **提示:使用web模式时,服务端执行文件必须在项目根目录,否则无法正确加载配置文件**
 
-### 使用
-
-
-
-**有两种模式:**
-
-1、单客户端模式,所有的隧道流量均从这个单客户端转发。
-
-
-- 服务端
-
-```
- ./proxy_server -vkey=DKibZF5TXvic1g3kY
-```
-名称 | 含义
----|---
-vkey | 验证密钥
-
-
-- 客户端
-
-```
- ./proxy_client -server=ip:port -vkey=DKibZF5TXvic1g3kY
-```
-- 配置
-
-进入web界面,公网ip:web界面端口(默认8080),密码默认为123
-
-2、多客户端模式,不同的隧道流量均从不同的客户端转发。
+### 启动
 
 
 - 服务端
@@ -125,10 +111,11 @@ vkey | 验证密钥
 ```
  ./proxy_server
 ```
-名称 | 含义
----|---
-mode | 运行模式
+
 - 客户端
+```
+ ./proxy_server -server=ip:port -vkey=web界面中显示的
+```
 
 进入web管理界面,有详细的命令
 
@@ -316,30 +303,31 @@ httpport | http代理连接端口
 配置HTTP代理即可,ip为外网服务器ip,端口为httpport,即可在外网环境访问内网啦!
 ```
 
-## 数据压缩支持
+## 相关功能
+
+### 数据压缩支持
 
 由于是内网穿透,内网客户端与服务端之间的隧道存在大量的数据交换,为节省流量,加快传输速度,由此本程序支持SNNAPY形式的压缩。
 
 
 - 所有模式均支持数据压缩,可以与加密同时使用
-
-
+- 开启此功能会增加cpu和内存消耗
 - 在server端加上参数 -compress=snappy(或在web管理中设置)
 ```
 -compress=snappy
 ```
 
-## 加密传输
+### 加密传输
 
 如果公司内网防火墙对外网访问进行了流量识别与屏蔽,例如禁止了ssh协议等,通过设置 配置文件,将服务端与客户端之间的通信内容加密传输,将会有效防止流量被拦截。
 
-
+- 开启此功能会增加cpu和内存消耗
 - 在server端加上参数 -crypt=true(或在web管理中设置)
 ```
 -crypt=true
 ```
 
-## 多路复用
+### 多路复用
 
 客户端和服务器端之间的连接支持多路复用,不再需要为每一个用户请求创建一个连接,使连接建立的延迟降低,并且避免了大量文件描述符的占用。
 
@@ -351,7 +339,7 @@ httpport | http代理连接端口
 ```
 
 
-## 站点保护
+### 站点保护
 由于所有客户端共用一个 http 服务端口,任何知道你的域名和 url 的人都能访问到你部署在内网的 web 服务,但是在某些场景下需要确保只有限定的用户才能访问。
 
 easyProxy支持通过 HTTP Basic Auth 来保护你的 web 服务,使用户需要通过用户名和密码才能访问到你的服务。
@@ -361,25 +349,37 @@ easyProxy支持通过 HTTP Basic Auth 来保护你的 web 服务,使用户需
 -u=user -p=password
 ```
 
-web管理中也可配置
+- web管理中也可配置
 
-## host修改
+### host修改
 
 
 通常情况下本代理不会修改转发的任何数据。但有一些后端服务会根据 http 请求 header 中的 host 字段来展现不同的网站,例如 nginx 的虚拟主机服务,启用 host-header 的修改功能可以动态修改 http 请求中的 host 字段。该功能仅限于域名代理模式。
 
 **使用方法:在web管理中设置**
 
-## 自定义header
+### 自定义header
 
 支持对header进行新增或者修改,以配合服务的需要
 
-## 获取用户真实ip
+### 获取用户真实ip
 
 目前只有域名模式的代理支持这一功能,可以通过用户请求的 header 中的 X-Forwarded-For 和 X-Real-IP 来获取用户真实 IP。
 
 **本代理前会在每一个请求中添加了这两个 header。**
 
+### 热更新支持
+在web管理中的修改将实时使用,无需重启客户端或者服务端
+
+### 客户端地址显示
+在web管理中将显示客户端的连接地址
+
+### 404页面配置
+支持域名解析模式的自定义404页面,修改/web/static/page/error.html中内容即可,暂不支持静态文件等内容
+
+### 流量统计
+可统计显示每个代理使用的流量,由于压缩和加密等原因,会和实际环境中的略有差异
+
+### 连接池
+ easyProxy会预先和后端服务建立起指定数量的连接,每次接收到用户请求后,会从连接池中取出一个连接和用户连接关联起来,避免了等待与后端服务建立连接时间。
 
-## 操作系统支持
-支持Windows、Linux、MacOSX等,无第三方依赖库。
diff --git a/bridge/bridge.go b/bridge/bridge.go
index 06a9b6c..8c6fa46 100755
--- a/bridge/bridge.go
+++ b/bridge/bridge.go
@@ -31,7 +31,7 @@ func newList() *list {
 	return l
 }
 
-type Tunnel struct {
+type Bridge struct {
 	TunnelPort int                 //通信隧道端口
 	listener   *net.TCPListener    //server端监听
 	SignalList map[int]*list       //通信
@@ -41,8 +41,8 @@ type Tunnel struct {
 	tunnelLock sync.Mutex
 }
 
-func NewTunnel(tunnelPort int, runList map[int]interface{}) *Tunnel {
-	t := new(Tunnel)
+func NewTunnel(tunnelPort int, runList map[int]interface{}) *Bridge {
+	t := new(Bridge)
 	t.TunnelPort = tunnelPort
 	t.SignalList = make(map[int]*list)
 	t.TunnelList = make(map[int]*list)
@@ -50,7 +50,7 @@ func NewTunnel(tunnelPort int, runList map[int]interface{}) *Tunnel {
 	return t
 }
 
-func (s *Tunnel) StartTunnel() error {
+func (s *Bridge) StartTunnel() error {
 	var err error
 	s.listener, err = net.ListenTCP("tcp", &net.TCPAddr{net.ParseIP("0.0.0.0"), s.TunnelPort, ""})
 	if err != nil {
@@ -61,7 +61,7 @@ func (s *Tunnel) StartTunnel() error {
 }
 
 //tcp server
-func (s *Tunnel) tunnelProcess() error {
+func (s *Bridge) tunnelProcess() error {
 	var err error
 	for {
 		conn, err := s.listener.Accept()
@@ -75,12 +75,12 @@ func (s *Tunnel) tunnelProcess() error {
 }
 
 //验证失败,返回错误验证flag,并且关闭连接
-func (s *Tunnel) verifyError(c *utils.Conn) {
+func (s *Bridge) verifyError(c *utils.Conn) {
 	c.Conn.Write([]byte(utils.VERIFY_EER))
 	c.Conn.Close()
 }
 
-func (s *Tunnel) cliProcess(c *utils.Conn) error {
+func (s *Bridge) cliProcess(c *utils.Conn) error {
 	c.Conn.(*net.TCPConn).SetReadDeadline(time.Now().Add(time.Duration(5) * time.Second))
 	vval := make([]byte, 32)
 	if _, err := c.Conn.Read(vval); err != nil {
@@ -104,7 +104,7 @@ func (s *Tunnel) cliProcess(c *utils.Conn) error {
 }
 
 //tcp连接类型区分
-func (s *Tunnel) typeDeal(typeVal string, c *utils.Conn, id int) error {
+func (s *Bridge) typeDeal(typeVal string, c *utils.Conn, id int) error {
 	switch typeVal {
 	case utils.WORK_MAIN:
 		log.Println("客户端连接成功", c.Conn.RemoteAddr())
@@ -119,7 +119,7 @@ func (s *Tunnel) typeDeal(typeVal string, c *utils.Conn, id int) error {
 }
 
 //加到对应的list中
-func (s *Tunnel) addList(m map[int]*list, c *utils.Conn, id int) {
+func (s *Bridge) addList(m map[int]*list, c *utils.Conn, id int) {
 	s.lock.Lock()
 	if v, ok := m[id]; ok {
 		v.Add(c)
@@ -132,7 +132,7 @@ func (s *Tunnel) addList(m map[int]*list, c *utils.Conn, id int) {
 }
 
 //新建隧道
-func (s *Tunnel) newChan(id int) error {
+func (s *Bridge) newChan(id int) error {
 	var connPass *utils.Conn
 	var err error
 retry:
@@ -148,7 +148,7 @@ retry:
 
 //得到一个tcp隧道
 //TODO 超时问题 锁机制问题 对单个客户端加锁
-func (s *Tunnel) GetTunnel(id int, en, de int, crypt, mux bool) (c *utils.Conn, err error) {
+func (s *Bridge) GetTunnel(id int, en, de int, crypt, mux bool) (c *utils.Conn, err error) {
 retry:
 	if c, err = s.waitAndPop(s.TunnelList, id); err != nil {
 		return
@@ -162,7 +162,7 @@ retry:
 }
 
 //得到一个通信通道
-func (s *Tunnel) GetSignal(id int) (err error, conn *utils.Conn) {
+func (s *Bridge) GetSignal(id int) (err error, conn *utils.Conn) {
 	if v, ok := s.SignalList[id]; !ok || v.Len() == 0 {
 		err = errors.New("客户端未连接")
 		return
@@ -172,14 +172,14 @@ func (s *Tunnel) GetSignal(id int) (err error, conn *utils.Conn) {
 }
 
 //重回slice 复用
-func (s *Tunnel) ReturnSignal(conn *utils.Conn, id int) {
+func (s *Bridge) ReturnSignal(conn *utils.Conn, id int) {
 	if v, ok := s.SignalList[id]; ok {
 		v.Add(conn)
 	}
 }
 
 //重回slice 复用
-func (s *Tunnel) ReturnTunnel(conn *utils.Conn, id int) {
+func (s *Bridge) ReturnTunnel(conn *utils.Conn, id int) {
 	if v, ok := s.TunnelList[id]; ok {
 		utils.FlushConn(conn.Conn)
 		v.Add(conn)
@@ -187,16 +187,16 @@ func (s *Tunnel) ReturnTunnel(conn *utils.Conn, id int) {
 }
 
 //删除通信通道
-func (s *Tunnel) DelClientSignal(id int) {
+func (s *Bridge) DelClientSignal(id int) {
 	s.delClient(id, s.SignalList)
 }
 
 //删除隧道
-func (s *Tunnel) DelClientTunnel(id int) {
+func (s *Bridge) DelClientTunnel(id int) {
 	s.delClient(id, s.TunnelList)
 }
 
-func (s *Tunnel) delClient(id int, l map[int]*list) {
+func (s *Bridge) delClient(id int, l map[int]*list) {
 	if t := l[id]; t != nil {
 		for {
 			if t.Len() <= 0 {
@@ -209,7 +209,7 @@ func (s *Tunnel) delClient(id int, l map[int]*list) {
 }
 
 //等待
-func (s *Tunnel) waitAndPop(m map[int]*list, id int) (c *utils.Conn, err error) {
+func (s *Bridge) waitAndPop(m map[int]*list, id int) (c *utils.Conn, err error) {
 	ticker := time.NewTicker(time.Millisecond * 100)
 	stop := time.After(time.Second * 3)
 	for {
@@ -231,7 +231,7 @@ func (s *Tunnel) waitAndPop(m map[int]*list, id int) (c *utils.Conn, err error)
 	return
 }
 
-func (s *Tunnel) verify(id int) bool {
+func (s *Bridge) verify(id int) bool {
 	for k := range s.RunList {
 		if k == id {
 			return true
diff --git a/cmd/proxy_server/proxy_server.go b/cmd/proxy_server/proxy_server.go
index 23bfb34..74d055b 100644
--- a/cmd/proxy_server/proxy_server.go
+++ b/cmd/proxy_server/proxy_server.go
@@ -24,22 +24,32 @@ var (
 
 func main() {
 	flag.Parse()
-	server.VerifyKey = *VerifyKey
-	cnf := &utils.ServerConfig{
-		TcpPort:        *httpPort,
-		Mode:           *rpMode,
-		Target:         *tunnelTarget,
-		VerifyKey:      *VerifyKey,
-		U:              *u,
-		P:              *p,
-		Compress:       *compress,
-		Start:          0,
-		IsRun:          0,
-		ClientStatus:   0,
-		Crypt:          utils.GetBoolByStr(*crypt),
-		Mux:            utils.GetBoolByStr(*mux),
-		CompressEncode: 0,
-		CompressDecode: 0,
+	task := &utils.Tunnel{
+		TcpPort: *httpPort,
+		Mode:    *rpMode,
+		Target:  *tunnelTarget,
+		Config: &utils.Config{
+			U:        *u,
+			P:        *p,
+			Compress: *compress,
+			Crypt:    utils.GetBoolByStr(*crypt),
+			Mux:      utils.GetBoolByStr(*mux),
+		},
+		Flow:         &utils.Flow{},
+		UseClientCnf: false,
+	}
+	if *VerifyKey != "" {
+		c := &utils.Client{
+			Id:        0,
+			VerifyKey: *VerifyKey,
+			Addr:      "",
+			Remark:    "",
+			Status:    true,
+			IsConnect: false,
+		}
+		c.Cnf.CompressDecode, c.Cnf.CompressEncode = utils.GetCompressType(c.Cnf.Compress)
+		server.CsvDb.Clients[0] = c
+		task.Client = c
 	}
 	if *TcpPort == 0 {
 		p, err := beego.AppConfig.Int("tcpport")
@@ -50,6 +60,6 @@ func main() {
 		}
 	}
 	log.Println("服务端启动,监听tcp服务端端口:", *TcpPort)
-	cnf.CompressDecode, cnf.CompressEncode = utils.GetCompressType(cnf.Compress)
-	server.StartNewServer(*TcpPort, cnf)
+	task.Config.CompressDecode, task.Config.CompressEncode = utils.GetCompressType(task.Config.Compress)
+	server.StartNewServer(*TcpPort, task)
 }
diff --git a/conf/clients.csv b/conf/clients.csv
index 206dcd6..5e3eeda 100644
--- a/conf/clients.csv
+++ b/conf/clients.csv
@@ -1,2 +1,2 @@
-2,zl4p3da659qa9rh3,127.0.0.1:58000,测试2,true,,,0,0,
 1,rfd0tl1anega0d0g,127.0.0.1:53603,测试,true,1,1,1,1,snappy
+2,zl4p3da659qa9rh3,127.0.0.1:52096,测试2,true,1,1,1,1,snappy
diff --git a/conf/hosts.csv b/conf/hosts.csv
index b4ba649..949dbc6 100644
--- a/conf/hosts.csv
+++ b/conf/hosts.csv
@@ -1,2 +1,2 @@
-a.o.com,127.0.0.1:8080,1,,,测试2
 b.o.com,127.0.0.1:8082,2,,,测试
+a.o.com,127.0.0.1:8080,1,Connection: close,,测试2
diff --git a/conf/tasks.csv b/conf/tasks.csv
index 4043561..442bf46 100644
--- a/conf/tasks.csv
+++ b/conf/tasks.csv
@@ -1,4 +1,5 @@
-9001,tunnelServer,127.0.0.1:8080,,,,1,0,0,0,0,1,1,true,test
-53,udpServer,114.114.114.114:53,,,,1,0,0,0,0,2,2,true,udp测试
-8024,socks5Server,,,,,1,0,0,0,0,3,2,true,socks5测试
-8025,httpProxyServer,,,,,1,0,0,0,0,4,2,true,http测试
+53,udpServer,114.114.114.114:53,,,,1,0,0,0,1,2,2,true,udp测试
+9001,tunnelServer,127.0.0.1:8080,1,1,snappy,1,1,1,0,0,1,1,false,test
+9009,tunnelServer,127.0.0.1:5900,,,,1,0,0,0,0,5,2,true,vnc
+8025,httpProxyServer,,2,2,snappy,1,1,1,0,0,4,2,false,http测试
+8024,socks5Server,,,,,1,0,0,0,0,3,2,false,socks5测试
diff --git a/image/web.png b/image/web.png
index c96aea8..ee59c81 100644
Binary files a/image/web.png and b/image/web.png differ
diff --git a/image/web2.png b/image/web2.png
index 63967d6..2b97c9c 100644
Binary files a/image/web2.png and b/image/web2.png differ
diff --git a/server/base.go b/server/base.go
index 74f1daf..90ab34a 100644
--- a/server/base.go
+++ b/server/base.go
@@ -8,53 +8,47 @@ import (
 
 //server base struct
 type server struct {
-	bridge *bridge.Tunnel
-	config *utils.ServerConfig
+	bridge *bridge.Bridge
+	task   *utils.Tunnel
+	config *utils.Config
 	sync.Mutex
 }
 
-func (s *server) GetTunnelAndWriteHost(connType string, cnf *utils.ServerConfig, addr string) (*utils.Conn, error) {
-	var err error
-	link, err := s.bridge.GetTunnel(cnf.ClientId, cnf.CompressEncode, cnf.CompressDecode, cnf.Crypt, cnf.Mux)
-	if err != nil {
-		return nil, err
+func (s *server) GetTunnelAndWriteHost(connType string, clientId int, cnf *utils.Config, addr string) (link *utils.Conn, err error) {
+	if link, err = s.bridge.GetTunnel(clientId, cnf.CompressEncode, cnf.CompressDecode, cnf.Crypt, cnf.Mux); err != nil {
+		return
 	}
 	if _, err = link.WriteHost(connType, addr); err != nil {
 		link.Close()
-		return nil, err
 	}
-	return link, nil
+	return
 }
 
 func (s *server) FlowAdd(in, out int64) {
 	s.Lock()
 	defer s.Unlock()
-	if s.config.Flow == nil {
-		s.config.Flow = new(utils.Flow)
-	}
-	s.config.Flow.ExportFlow += out
-	s.config.Flow.InletFlow += in
+	s.task.Flow.ExportFlow += out
+	s.task.Flow.InletFlow += in
 }
 
-func (s *server) FlowAddHost(host *utils.HostList, in, out int64) {
+func (s *server) FlowAddHost(host *utils.Host, in, out int64) {
 	s.Lock()
 	defer s.Unlock()
-	if s.config.Flow == nil {
-		s.config.Flow = new(utils.Flow)
-	}
 	host.Flow.ExportFlow += out
 	host.Flow.InletFlow += in
 }
 
 //热更新配置
 func (s *server) ResetConfig() {
-	task, err := CsvDb.GetTask(s.config.Id)
+	//获取最新数据
+	task, err := CsvDb.GetTask(s.task.Id)
 	if err != nil {
 		return
 	}
-	s.config.UseClientCnf = task.UseClientCnf
-	if s.config.UseClientCnf {
-		client, err := CsvDb.GetClient(s.config.ClientId)
+	s.task.UseClientCnf = task.UseClientCnf
+	//使用客户端配置
+	if s.task.UseClientCnf {
+		client, err := CsvDb.GetClient(s.task.Client.Id)
 		if err == nil {
 			s.config.U = client.Cnf.U
 			s.config.P = client.Cnf.P
@@ -62,15 +56,14 @@ func (s *server) ResetConfig() {
 			s.config.Mux = client.Cnf.Mux
 			s.config.Crypt = client.Cnf.Crypt
 		}
-		s.config.CompressDecode, s.config.CompressEncode = utils.GetCompressType(client.Cnf.Compress)
 	} else {
 		if err == nil {
-			s.config.U = task.U
-			s.config.P = task.P
-			s.config.Compress = task.Compress
-			s.config.Mux = task.Mux
-			s.config.Crypt = task.Crypt
+			s.config.U = task.Config.U
+			s.config.P = task.Config.P
+			s.config.Compress = task.Config.Compress
+			s.config.Mux = task.Config.Mux
+			s.config.Crypt = task.Config.Crypt
 		}
-		s.config.CompressDecode, s.config.CompressEncode = utils.GetCompressType(task.Compress)
 	}
+	s.config.CompressDecode, s.config.CompressEncode = utils.GetCompressType(s.config.Compress)
 }
diff --git a/server/process.go b/server/process.go
index f564bfd..341a3a0 100644
--- a/server/process.go
+++ b/server/process.go
@@ -13,13 +13,7 @@ type process func(c *utils.Conn, s *TunnelModeServer) error
 
 //tcp隧道模式
 func ProcessTunnel(c *utils.Conn, s *TunnelModeServer) error {
-	_, _, rb, err, r := c.GetHost()
-	if err == nil {
-		if err := s.auth(r, c, s.config.U, s.config.P); err != nil {
-			return err
-		}
-	}
-	return s.dealClient(c, s.config, s.config.Target, "", rb)
+	return s.dealClient(c, s.config, s.task.Target, "", nil)
 }
 
 //http代理模式
@@ -41,8 +35,7 @@ func ProcessHost(c *utils.Conn, s *TunnelModeServer) error {
 	var (
 		isConn = true
 		link   *utils.Conn
-		client *utils.Client
-		host   *utils.HostList
+		host   *utils.Host
 		wg     sync.WaitGroup
 	)
 	for {
@@ -52,17 +45,17 @@ func ProcessHost(c *utils.Conn, s *TunnelModeServer) error {
 		}
 		//首次获取conn
 		if isConn {
-			if host, client, err = GetKeyByHost(r.Host); err != nil {
+			if host, err = GetInfoByHost(r.Host); err != nil {
 				log.Printf("the host %s is not found !", r.Host)
 				break
 			}
 
-			client.Cnf.ClientId = host.ClientId
-			client.Cnf.CompressDecode, client.Cnf.CompressEncode = utils.GetCompressType(client.Cnf.Compress)
-			if err = s.auth(r, c, client.Cnf.U, client.Cnf.P); err != nil {
+			host.Client.Cnf.CompressDecode, host.Client.Cnf.CompressEncode = utils.GetCompressType(host.Client.Cnf.Compress)
+
+			if err = s.auth(r, c, host.Client.Cnf.U, host.Client.Cnf.P); err != nil {
 				break
 			}
-			if link, err = s.GetTunnelAndWriteHost(utils.CONN_TCP, client.Cnf, host.Target); err != nil {
+			if link, err = s.GetTunnelAndWriteHost(utils.CONN_TCP, host.Client.Id, host.Client.Cnf, host.Target); err != nil {
 				log.Println("get bridge tunnel error: ", err)
 				break
 			}
@@ -72,27 +65,28 @@ func ProcessHost(c *utils.Conn, s *TunnelModeServer) error {
 			} else {
 				wg.Add(1)
 				go func() {
-					out, _ := utils.Relay(c.Conn, link.Conn, client.Cnf.CompressDecode, client.Cnf.Crypt, client.Cnf.Mux)
+					out, _ := utils.Relay(c.Conn, link.Conn, host.Client.Cnf.CompressDecode, host.Client.Cnf.Crypt, host.Client.Cnf.Mux)
 					wg.Done()
 					s.FlowAddHost(host, 0, out)
 				}()
 			}
 			isConn = false
 		}
+		//根据设定,修改header和host
 		utils.ChangeHostAndHeader(r, host.HostChange, host.HeaderChange, c.Conn.RemoteAddr().String())
 		b, err := httputil.DumpRequest(r, true)
-		s.FlowAddHost(host, int64(len(b)), 0)
 		if err != nil {
 			break
 		}
-		if _, err := link.WriteTo(b, client.Cnf.CompressEncode, client.Cnf.Crypt); err != nil {
+		s.FlowAddHost(host, int64(len(b)), 0)
+		if _, err := link.WriteTo(b, host.Client.Cnf.CompressEncode, host.Client.Cnf.Crypt); err != nil {
 			break
 		}
 	}
 	wg.Wait()
-	if client != nil && client.Cnf != nil && client.Cnf.Mux && link != nil {
-		link.WriteTo([]byte(utils.IO_EOF), client.Cnf.CompressEncode, client.Cnf.Crypt)
-		s.bridge.ReturnTunnel(link, client.Id)
+	if host != nil && host.Client.Cnf != nil && host.Client.Cnf.Mux && link != nil {
+		link.WriteTo([]byte(utils.IO_EOF), host.Client.Cnf.CompressEncode, host.Client.Cnf.Crypt)
+		s.bridge.ReturnTunnel(link, host.Client.Id)
 	} else if link != nil {
 		link.Close()
 	}
@@ -103,5 +97,3 @@ func ProcessHost(c *utils.Conn, s *TunnelModeServer) error {
 	c.Close()
 	return nil
 }
-
-
diff --git a/server/server.go b/server/server.go
index 06dfe51..c9808ca 100644
--- a/server/server.go
+++ b/server/server.go
@@ -20,10 +20,9 @@ type RunServer struct {
 }
 
 var (
-	Bridge    *bridge.Tunnel
+	Bridge    *bridge.Bridge
 	RunList   map[int]interface{} //运行中的任务
 	CsvDb     = utils.GetCsvDb()
-	VerifyKey string
 )
 
 func init() {
@@ -33,7 +32,7 @@ func init() {
 //从csv文件中恢复任务
 func InitFromCsv() {
 	for _, v := range CsvDb.Tasks {
-		if v.Start == 1 {
+		if v.Status {
 			log.Println("启动模式:", v.Mode, "监听端口:", v.TcpPort)
 			AddTask(v)
 		}
@@ -41,7 +40,7 @@ func InitFromCsv() {
 }
 
 //start a new server
-func StartNewServer(bridgePort int, cnf *utils.ServerConfig) {
+func StartNewServer(bridgePort int, cnf *utils.Tunnel) {
 	Bridge = bridge.NewTunnel(bridgePort, RunList)
 	if err := Bridge.StartTunnel(); err != nil {
 		log.Fatalln("服务端开启失败", err)
@@ -58,37 +57,32 @@ func StartNewServer(bridgePort int, cnf *utils.ServerConfig) {
 }
 
 //new a server by mode name
-func NewMode(Bridge *bridge.Tunnel, c *utils.ServerConfig) interface{} {
-	config := utils.DeepCopyConfig(c)
-	switch config.Mode {
+func NewMode(Bridge *bridge.Bridge, c *utils.Tunnel) interface{} {
+	switch c.Mode {
 	case "tunnelServer":
-		return NewTunnelModeServer(ProcessTunnel, Bridge, config)
+		return NewTunnelModeServer(ProcessTunnel, Bridge, c)
 	case "socks5Server":
-		return NewSock5ModeServer(Bridge, config)
+		return NewSock5ModeServer(Bridge, c)
 	case "httpProxyServer":
-		return NewTunnelModeServer(ProcessHttp, Bridge, config)
+		return NewTunnelModeServer(ProcessHttp, Bridge, c)
 	case "udpServer":
-		return NewUdpModeServer(Bridge, config)
+		return NewUdpModeServer(Bridge, c)
 	case "webServer":
 		InitFromCsv()
 		p, _ := beego.AppConfig.Int("hostPort")
-		t := &utils.ServerConfig{
-			TcpPort:      p,
-			Mode:         "httpHostServer",
-			Target:       "",
-			U:            "",
-			P:            "",
-			Compress:     "",
-			Start:        1,
-			IsRun:        0,
-			ClientStatus: 0,
+		t := &utils.Tunnel{
+			TcpPort: p,
+			Mode:    "httpHostServer",
+			Target:  "",
+			Config:  &utils.Config{},
+			Status:  true,
 		}
 		AddTask(t)
 		return NewWebServer(Bridge)
 	case "hostServer":
-		return NewHostServer(config)
+		return NewHostServer(c)
 	case "httpHostServer":
-		return NewTunnelModeServer(ProcessHost, Bridge, config)
+		return NewTunnelModeServer(ProcessHost, Bridge, c)
 	}
 	return nil
 }
@@ -100,7 +94,7 @@ func StopServer(id int) error {
 		if t, err := CsvDb.GetTask(id); err != nil {
 			return err
 		} else {
-			t.Start = 0
+			t.Status = false
 			CsvDb.UpdateTask(t)
 		}
 		return nil
@@ -109,7 +103,7 @@ func StopServer(id int) error {
 }
 
 //add task
-func AddTask(t *utils.ServerConfig) error {
+func AddTask(t *utils.Tunnel) error {
 	if svr := NewMode(Bridge, t); svr != nil {
 		RunList[t.Id] = svr
 		go func() {
@@ -131,7 +125,7 @@ func StartTask(id int) error {
 		return err
 	} else {
 		AddTask(t)
-		t.Start = 1
+		t.Status = true
 		CsvDb.UpdateTask(t)
 	}
 	return nil
@@ -146,12 +140,11 @@ func DelTask(id int) error {
 }
 
 //get key by host from x
-func GetKeyByHost(host string) (h *utils.HostList, t *utils.Client, err error) {
+func GetInfoByHost(host string) (h *utils.Host, err error) {
 	for _, v := range CsvDb.Hosts {
 		s := strings.Split(host, ":")
 		if s[0] == v.Host {
 			h = v
-			t, err = CsvDb.GetClient(v.ClientId)
 			return
 		}
 	}
@@ -160,39 +153,25 @@ func GetKeyByHost(host string) (h *utils.HostList, t *utils.Client, err error) {
 }
 
 //get task list by page num
-func GetServerConfig(start, length int, typeVal string, clientId int) ([]*utils.ServerConfig, int) {
-	list := make([]*utils.ServerConfig, 0)
+func GetTunnel(start, length int, typeVal string, clientId int) ([]*utils.Tunnel, int) {
+	list := make([]*utils.Tunnel, 0)
 	var cnt int
 	for _, v := range CsvDb.Tasks {
-		if (typeVal != "" && v.Mode != typeVal) || (typeVal == "" && clientId != v.ClientId) {
+		if (typeVal != "" && v.Mode != typeVal) || (typeVal == "" && clientId != v.Client.Id) {
 			continue
 		}
-		if v.UseClientCnf {
-			v = utils.DeepCopyConfig(v)
-			if c, err := CsvDb.GetClient(v.ClientId); err == nil {
-				v.Compress = c.Cnf.Compress
-				v.Mux = c.Cnf.Mux
-				v.Crypt = c.Cnf.Crypt
-				v.U = c.Cnf.U
-				v.P = c.Cnf.P
-			}
-		}
 		cnt++
+		if _, ok := Bridge.SignalList[v.Client.Id]; ok {
+			v.Client.IsConnect = true
+		} else {
+			v.Client.IsConnect = false
+		}
 		if start--; start < 0 {
 			if length--; length > 0 {
 				if _, ok := RunList[v.Id]; ok {
-					v.IsRun = 1
+					v.Client.Status = true
 				} else {
-					v.IsRun = 0
-				}
-				if s, ok := Bridge.SignalList[v.ClientId]; ok {
-					if s.Len() > 0 {
-						v.ClientStatus = 1
-					} else {
-						v.ClientStatus = 0
-					}
-				} else {
-					v.ClientStatus = 0
+					v.Client.Status = false
 				}
 				list = append(list, v)
 			}
@@ -218,13 +197,13 @@ func dealClientData(list []*utils.Client) {
 		v.Flow.InletFlow = 0
 		v.Flow.ExportFlow = 0
 		for _, h := range CsvDb.Hosts {
-			if h.ClientId == v.Id {
+			if h.Client.Id == v.Id {
 				v.Flow.InletFlow += h.Flow.InletFlow
 				v.Flow.ExportFlow += h.Flow.ExportFlow
 			}
 		}
 		for _, t := range CsvDb.Tasks {
-			if t.ClientId == v.Id {
+			if t.Client.Id == v.Id {
 				v.Flow.InletFlow += t.Flow.InletFlow
 				v.Flow.ExportFlow += t.Flow.ExportFlow
 			}
@@ -236,12 +215,12 @@ func dealClientData(list []*utils.Client) {
 //根据客户端id删除其所属的所有隧道和域名
 func DelTunnelAndHostByClientId(clientId int) {
 	for _, v := range CsvDb.Tasks {
-		if v.ClientId == clientId {
+		if v.Client.Id == clientId {
 			DelTask(v.Id)
 		}
 	}
 	for _, v := range CsvDb.Hosts {
-		if v.ClientId == clientId {
+		if v.Client.Id == clientId {
 			CsvDb.DelHost(v.Host)
 		}
 	}
diff --git a/server/socks5.go b/server/socks5.go
index f8f9211..4c14c85 100755
--- a/server/socks5.go
+++ b/server/socks5.go
@@ -141,7 +141,7 @@ func (s *Sock5ModeServer) doConnect(c net.Conn, command uint8) (proxyConn *utils
 	} else {
 		ltype = utils.CONN_TCP
 	}
-	if proxyConn, err = s.GetTunnelAndWriteHost(ltype, s.config, addr); err != nil {
+	if proxyConn, err = s.GetTunnelAndWriteHost(ltype, s.task.Client.Id, s.config, addr); err != nil {
 		log.Println("get bridge tunnel error: ", err)
 		return
 	}
@@ -160,7 +160,7 @@ func (s *Sock5ModeServer) handleConnect(c net.Conn) {
 	proxyConn, err := s.doConnect(c, connectMethod)
 	defer func() {
 		if s.config.Mux && proxyConn != nil {
-			s.bridge.ReturnTunnel(proxyConn, s.config.ClientId)
+			s.bridge.ReturnTunnel(proxyConn, s.task.Client.Id)
 		}
 	}()
 	if err != nil {
@@ -198,7 +198,7 @@ func (s *Sock5ModeServer) handleUDP(c net.Conn) {
 	proxyConn, err := s.doConnect(c, associateMethod)
 	defer func() {
 		if s.config.Mux && proxyConn != nil {
-			s.bridge.ReturnTunnel(proxyConn, s.config.ClientId)
+			s.bridge.ReturnTunnel(proxyConn, s.task.Client.Id)
 		}
 	}()
 	if err != nil {
@@ -285,7 +285,7 @@ func (s *Sock5ModeServer) Auth(c net.Conn) error {
 //start
 func (s *Sock5ModeServer) Start() error {
 	var err error
-	s.listener, err = net.Listen("tcp", ":"+strconv.Itoa(s.config.TcpPort))
+	s.listener, err = net.Listen("tcp", ":"+strconv.Itoa(s.task.TcpPort))
 	if err != nil {
 		return err
 	}
@@ -309,10 +309,11 @@ func (s *Sock5ModeServer) Close() error {
 }
 
 //new
-func NewSock5ModeServer(bridge *bridge.Tunnel, cnf *utils.ServerConfig) *Sock5ModeServer {
+func NewSock5ModeServer(bridge *bridge.Bridge, task *utils.Tunnel) *Sock5ModeServer {
 	s := new(Sock5ModeServer)
 	s.bridge = bridge
-	s.config = cnf
+	s.task = task
+	s.config = utils.DeepCopyConfig(task.Config)
 	if s.config.U != "" && s.config.P != "" {
 		s.isVerify = true
 	} else {
diff --git a/server/tcp.go b/server/tcp.go
index d47ae43..810123a 100755
--- a/server/tcp.go
+++ b/server/tcp.go
@@ -20,11 +20,12 @@ type TunnelModeServer struct {
 }
 
 //tcp|http|host
-func NewTunnelModeServer(process process, bridge *bridge.Tunnel, cnf *utils.ServerConfig) *TunnelModeServer {
+func NewTunnelModeServer(process process, bridge *bridge.Bridge, task *utils.Tunnel) *TunnelModeServer {
 	s := new(TunnelModeServer)
 	s.bridge = bridge
 	s.process = process
-	s.config = cnf
+	s.task = task
+	s.config = utils.DeepCopyConfig(task.Config)
 	return s
 }
 
@@ -34,7 +35,7 @@ func (s *TunnelModeServer) Start() error {
 	if s.errorContent, err = utils.ReadAllFromFile(beego.AppPath + "/web/static/page/error.html"); err != nil {
 		s.errorContent = []byte("easyProxy 404")
 	}
-	s.listener, err = net.ListenTCP("tcp", &net.TCPAddr{net.ParseIP("0.0.0.0"), s.config.TcpPort, ""})
+	s.listener, err = net.ListenTCP("tcp", &net.TCPAddr{net.ParseIP("0.0.0.0"), s.task.TcpPort, ""})
 	if err != nil {
 		return err
 	}
@@ -69,15 +70,15 @@ func (s *TunnelModeServer) writeConnFail(c net.Conn) {
 }
 
 //与客户端建立通道
-func (s *TunnelModeServer) dealClient(c *utils.Conn, cnf *utils.ServerConfig, addr string, method string, rb []byte) error {
+func (s *TunnelModeServer) dealClient(c *utils.Conn, cnf *utils.Config, addr string, method string, rb []byte) error {
 	var link *utils.Conn
 	var err error
 	defer func() {
 		if cnf.Mux && link != nil {
-			s.bridge.ReturnTunnel(link, cnf.ClientId)
+			s.bridge.ReturnTunnel(link, s.task.Client.Id)
 		}
 	}()
-	if link, err = s.GetTunnelAndWriteHost(utils.CONN_TCP, cnf, addr); err != nil {
+	if link, err = s.GetTunnelAndWriteHost(utils.CONN_TCP, s.task.Client.Id, cnf, addr); err != nil {
 		log.Println("get bridge tunnel error: ", err)
 		return err
 	}
@@ -115,7 +116,7 @@ func (s *WebServer) Start() {
 }
 
 //new
-func NewWebServer(bridge *bridge.Tunnel) *WebServer {
+func NewWebServer(bridge *bridge.Bridge) *WebServer {
 	s := new(WebServer)
 	s.bridge = bridge
 	return s
@@ -131,9 +132,10 @@ func (s *HostServer) Start() error {
 	return nil
 }
 
-func NewHostServer(cnf *utils.ServerConfig) *HostServer {
+func NewHostServer(task *utils.Tunnel) *HostServer {
 	s := new(HostServer)
-	s.config = cnf
+	s.task = task
+	s.config = utils.DeepCopyConfig(task.Config)
 	return s
 }
 
diff --git a/server/udp.go b/server/udp.go
index 7ede79e..72661d0 100755
--- a/server/udp.go
+++ b/server/udp.go
@@ -15,18 +15,19 @@ type UdpModeServer struct {
 	udpMap   map[string]*utils.Conn
 }
 
-func NewUdpModeServer(bridge *bridge.Tunnel, cnf *utils.ServerConfig) *UdpModeServer {
+func NewUdpModeServer(bridge *bridge.Bridge, task *utils.Tunnel) *UdpModeServer {
 	s := new(UdpModeServer)
 	s.bridge = bridge
 	s.udpMap = make(map[string]*utils.Conn)
-	s.config = cnf
+	s.task = task
+	s.config = utils.DeepCopyConfig(task.Config)
 	return s
 }
 
 //开始
 func (s *UdpModeServer) Start() error {
 	var err error
-	s.listener, err = net.ListenUDP("udp", &net.UDPAddr{net.ParseIP("0.0.0.0"), s.config.TcpPort, ""})
+	s.listener, err = net.ListenUDP("udp", &net.UDPAddr{net.ParseIP("0.0.0.0"), s.task.TcpPort, ""})
 	if err != nil {
 		return err
 	}
@@ -45,14 +46,14 @@ func (s *UdpModeServer) Start() error {
 	return nil
 }
 
-//TODO:效率问题有待解决
+//TODO:效率问题有待解决--->建立稳定通道,重复利用,提高效率,下个版本
 func (s *UdpModeServer) process(addr *net.UDPAddr, data []byte) {
-	conn, err := s.bridge.GetTunnel(s.config.ClientId, s.config.CompressEncode, s.config.CompressDecode, s.config.Crypt, s.config.Mux)
+	conn, err := s.bridge.GetTunnel(s.task.Client.Id, s.config.CompressEncode, s.config.CompressDecode, s.config.Crypt, s.config.Mux)
 	if err != nil {
 		log.Println(err)
 		return
 	}
-	if _, err := conn.WriteHost(utils.CONN_UDP, s.config.Target); err != nil {
+	if _, err := conn.WriteHost(utils.CONN_UDP, s.task.Target); err != nil {
 		conn.Close()
 		return
 	}
@@ -60,7 +61,7 @@ func (s *UdpModeServer) process(addr *net.UDPAddr, data []byte) {
 		defer func() {
 			if conn != nil && s.config.Mux {
 				conn.WriteTo([]byte(utils.IO_EOF), s.config.CompressEncode, s.config.Crypt)
-				s.bridge.ReturnTunnel(conn, s.config.ClientId)
+				s.bridge.ReturnTunnel(conn, s.task.Client.Id)
 			} else {
 				conn.Close()
 			}
@@ -70,7 +71,6 @@ func (s *UdpModeServer) process(addr *net.UDPAddr, data []byte) {
 			buf := utils.BufPoolUdp.Get().([]byte)
 			out, err := conn.ReadFrom(buf, s.config.CompressDecode, s.config.Crypt)
 			if err != nil || err == io.EOF {
-				log.Println("revieve error:", err)
 				return
 			}
 			s.listener.WriteToUDP(buf[:out], addr)
diff --git a/utils/file.go b/utils/file.go
index f892fa6..38eac89 100644
--- a/utils/file.go
+++ b/utils/file.go
@@ -22,7 +22,7 @@ type Flow struct {
 }
 
 type Client struct {
-	Cnf       *ServerConfig
+	Cnf       *Config
 	Id        int    //id
 	VerifyKey string //验证密钥
 	Addr      string //客户端ip地址
@@ -32,35 +32,36 @@ type Client struct {
 	Flow      *Flow
 }
 
-type ServerConfig struct {
-	TcpPort        int //服务端与客户端通信端口
-	VerifyKey      string
-	Mode           string //启动方式
-	Target         string //目标
+type Tunnel struct {
+	Id           int     //Id
+	TcpPort      int     //服务端与客户端通信端口
+	Mode         string  //启动方式
+	Target       string  //目标
+	Status       bool    //是否开启
+	Client       *Client //所属客户端id
+	Flow         *Flow
+	Config       *Config
+	UseClientCnf bool   //是否继承客户端配置
+	Remark       string //备注
+}
+
+type Config struct {
 	U              string //socks5验证用户名
 	P              string //socks5验证密码
 	Compress       string //压缩方式
-	Start          int    //是否开启
-	IsRun          int    //是否在运行
-	ClientStatus   int    //客s户端状态
 	Crypt          bool   //是否加密
 	Mux            bool   //是否加密
 	CompressEncode int    //加密方式
 	CompressDecode int    //解密方式
-	Id             int    //Id
-	ClientId       int    //所属客户端id
-	UseClientCnf   bool   //是否继承客户端配置
-	Flow           *Flow
-	Remark         string //备注
 }
 
-type HostList struct {
-	ClientId     int    //服务端与客户端通信端口
+type Host struct {
 	Host         string //启动方式
 	Target       string //目标
 	HeaderChange string //host修改
 	HostChange   string //host修改
 	Flow         *Flow
+	Client       *Client
 	Remark       string //备注
 }
 
@@ -70,19 +71,19 @@ func NewCsv() *Csv {
 }
 
 type Csv struct {
-	Tasks            []*ServerConfig
+	Tasks            []*Tunnel
 	Path             string
-	Hosts            []*HostList //域名列表
-	Clients          []*Client   //客户端
-	ClientIncreaseId int         //客户端id
-	TaskIncreaseId   int         //任务自增ID
+	Hosts            []*Host   //域名列表
+	Clients          []*Client //客户端
+	ClientIncreaseId int       //客户端id
+	TaskIncreaseId   int       //任务自增ID
 	sync.Mutex
 }
 
 func (s *Csv) Init() {
+	s.LoadClientFromCsv()
 	s.LoadTaskFromCsv()
 	s.LoadHostFromCsv()
-	s.LoadClientFromCsv()
 }
 
 func (s *Csv) StoreTasksToCsv() {
@@ -98,16 +99,16 @@ func (s *Csv) StoreTasksToCsv() {
 			strconv.Itoa(task.TcpPort),
 			task.Mode,
 			task.Target,
-			task.U,
-			task.P,
-			task.Compress,
-			strconv.Itoa(task.Start),
-			GetStrByBool(task.Crypt),
-			GetStrByBool(task.Mux),
-			strconv.Itoa(task.CompressEncode),
-			strconv.Itoa(task.CompressDecode),
+			task.Config.U,
+			task.Config.P,
+			task.Config.Compress,
+			utils.GetStrByBool(task.Status),
+			GetStrByBool(task.Config.Crypt),
+			GetStrByBool(task.Config.Mux),
+			strconv.Itoa(task.Config.CompressEncode),
+			strconv.Itoa(task.Config.CompressDecode),
 			strconv.Itoa(task.Id),
-			strconv.Itoa(task.ClientId),
+			strconv.Itoa(task.Client.Id),
 			strconv.FormatBool(task.UseClientCnf),
 			task.Remark,
 		}
@@ -143,27 +144,31 @@ func (s *Csv) LoadTaskFromCsv() {
 	if err != nil {
 		log.Fatal("配置文件打开错误:", path)
 	}
-	var tasks []*ServerConfig
+	var tasks []*Tunnel
 	// 将每一行数据保存到内存slice中
 	for _, item := range records {
-		post := &ServerConfig{
-			TcpPort:        GetIntNoErrByStr(item[0]),
-			Mode:           item[1],
-			Target:         item[2],
-			U:              item[3],
-			P:              item[4],
-			Compress:       item[5],
-			Start:          GetIntNoErrByStr(item[6]),
-			Crypt:          GetBoolByStr(item[7]),
-			Mux:            GetBoolByStr(item[8]),
-			CompressEncode: GetIntNoErrByStr(item[9]),
-			CompressDecode: GetIntNoErrByStr(item[10]),
-			Id:             GetIntNoErrByStr(item[11]),
-			ClientId:       GetIntNoErrByStr(item[12]),
-			UseClientCnf:   GetBoolByStr(item[13]),
-			Remark:         item[14],
+		post := &Tunnel{
+			TcpPort: GetIntNoErrByStr(item[0]),
+			Mode:    item[1],
+			Target:  item[2],
+			Config: &Config{
+				U:              item[3],
+				P:              item[4],
+				Compress:       item[5],
+				Crypt:          GetBoolByStr(item[7]),
+				Mux:            GetBoolByStr(item[8]),
+				CompressEncode: GetIntNoErrByStr(item[9]),
+				CompressDecode: GetIntNoErrByStr(item[10]),
+			},
+			Status:       utils.GetBoolByStr(item[6]),
+			Id:           GetIntNoErrByStr(item[11]),
+			UseClientCnf: GetBoolByStr(item[13]),
+			Remark:       item[14],
 		}
 		post.Flow = new(Flow)
+		if post.Client, err = s.GetClient(GetIntNoErrByStr(item[12])); err != nil {
+			continue
+		}
 		tasks = append(tasks, post)
 		if post.Id > s.TaskIncreaseId {
 			s.TaskIncreaseId = post.Id
@@ -191,13 +196,13 @@ func (s *Csv) GetIdByVerifyKey(vKey string, addr string) (int, error) {
 	return 0, errors.New("not found")
 }
 
-func (s *Csv) NewTask(t *ServerConfig) {
+func (s *Csv) NewTask(t *Tunnel) {
 	t.Flow = new(Flow)
 	s.Tasks = append(s.Tasks, t)
 	s.StoreTasksToCsv()
 }
 
-func (s *Csv) UpdateTask(t *ServerConfig) error {
+func (s *Csv) UpdateTask(t *Tunnel) error {
 	for k, v := range s.Tasks {
 		if v.Id == t.Id {
 			s.Tasks = append(s.Tasks[:k], s.Tasks[k+1:]...)
@@ -220,7 +225,7 @@ func (s *Csv) DelTask(id int) error {
 	return errors.New("不存在")
 }
 
-func (s *Csv) GetTask(id int) (v *ServerConfig, err error) {
+func (s *Csv) GetTask(id int) (v *Tunnel, err error) {
 	for _, v = range s.Tasks {
 		if v.Id == id {
 			return
@@ -245,7 +250,7 @@ func (s *Csv) StoreHostToCsv() {
 		record := []string{
 			host.Host,
 			host.Target,
-			strconv.Itoa(host.ClientId),
+			strconv.Itoa(host.Client.Id),
 			host.HeaderChange,
 			host.HostChange,
 			host.Remark,
@@ -274,7 +279,7 @@ func (s *Csv) LoadClientFromCsv() {
 			Addr:      item[2],
 			Remark:    item[3],
 			Status:    GetBoolByStr(item[4]),
-			Cnf: &ServerConfig{
+			Cnf: &Config{
 				U:        item[5],
 				P:        item[6],
 				Crypt:    GetBoolByStr(item[7]),
@@ -297,17 +302,19 @@ func (s *Csv) LoadHostFromCsv() {
 	if err != nil {
 		log.Fatal("配置文件打开错误:", path)
 	}
-	var hosts []*HostList
+	var hosts []*Host
 	// 将每一行数据保存到内存slice中
 	for _, item := range records {
-		post := &HostList{
-			ClientId:     GetIntNoErrByStr(item[2]),
+		post := &Host{
 			Host:         item[0],
 			Target:       item[1],
 			HeaderChange: item[3],
 			HostChange:   item[4],
 			Remark:       item[5],
 		}
+		if post.Client, err = s.GetClient(GetIntNoErrByStr(item[2])); err != nil {
+			continue
+		}
 		post.Flow = new(Flow)
 		hosts = append(hosts, post)
 	}
@@ -325,14 +332,14 @@ func (s *Csv) DelHost(host string) error {
 	return errors.New("不存在")
 }
 
-func (s *Csv) NewHost(t *HostList) {
+func (s *Csv) NewHost(t *Host) {
 	t.Flow = new(Flow)
 	s.Hosts = append(s.Hosts, t)
 	s.StoreHostToCsv()
 
 }
 
-func (s *Csv) UpdateHost(t *HostList) error {
+func (s *Csv) UpdateHost(t *Host) error {
 	for k, v := range s.Hosts {
 		if v.Host == t.Host {
 			s.Hosts = append(s.Hosts[:k], s.Hosts[k+1:]...)
@@ -344,11 +351,11 @@ func (s *Csv) UpdateHost(t *HostList) error {
 	return errors.New("不存在")
 }
 
-func (s *Csv) GetHostList(start, length int, id int) ([]*HostList, int) {
-	list := make([]*HostList, 0)
+func (s *Csv) GetHost(start, length int, id int) ([]*Host, int) {
+	list := make([]*Host, 0)
 	var cnt int
 	for _, v := range s.Hosts {
-		if id == 0 || v.ClientId == id {
+		if id == 0 || v.Client.Id == id {
 			cnt++
 			if start--; start < 0 {
 				if length--; length > 0 {
@@ -461,27 +468,15 @@ func GetCsvDb() *Csv {
 	return CsvDb
 }
 
-//深拷贝serverConfig
-func DeepCopyConfig(c *ServerConfig) *ServerConfig {
-	return &ServerConfig{
-		TcpPort:        c.TcpPort,
-		VerifyKey:      c.VerifyKey,
-		Mode:           c.Mode,
-		Target:         c.Target,
+//深拷贝Tunnel
+func DeepCopyConfig(c *Config) *Config {
+	return &Config{
 		U:              c.U,
 		P:              c.P,
 		Compress:       c.Compress,
-		Start:          c.Start,
-		IsRun:          c.IsRun,
-		ClientStatus:   c.ClientStatus,
 		Crypt:          c.Crypt,
 		Mux:            c.Mux,
 		CompressEncode: c.CompressEncode,
 		CompressDecode: c.CompressDecode,
-		Id:             c.Id,
-		ClientId:       c.ClientId,
-		UseClientCnf:   c.UseClientCnf,
-		Flow:           c.Flow,
-		Remark:         c.Remark,
 	}
 }
diff --git a/utils/util.go b/utils/util.go
index 89b9b11..a717802 100755
--- a/utils/util.go
+++ b/utils/util.go
@@ -240,6 +240,5 @@ func ReadAllFromFile(filePth string) ([]byte, error) {
 	if err != nil {
 		return nil, err
 	}
-
 	return ioutil.ReadAll(f)
 }
diff --git a/web/controllers/client.go b/web/controllers/client.go
index c7d943d..4058b63 100644
--- a/web/controllers/client.go
+++ b/web/controllers/client.go
@@ -33,7 +33,7 @@ func (s *ClientController) Add() {
 			Id:        server.CsvDb.GetClientId(),
 			Status:    true,
 			Remark:    s.GetString("Remark"),
-			Cnf: &utils.ServerConfig{
+			Cnf: &utils.Config{
 				U:        s.GetString("u"),
 				P:        s.GetString("p"),
 				Compress: s.GetString("compress"),
diff --git a/web/controllers/index.go b/web/controllers/index.go
index d827542..1fcfdaf 100755
--- a/web/controllers/index.go
+++ b/web/controllers/index.go
@@ -57,11 +57,11 @@ func (s *IndexController) All() {
 	s.display("index/list")
 }
 
-func (s *IndexController) GetServerConfig() {
+func (s *IndexController) GetTunnel() {
 	start, length := s.GetAjaxParams()
 	taskType := s.GetString("type")
 	clientId := s.GetIntNoErr("client_id")
-	list, cnt := server.GetServerConfig(start, length, taskType, clientId)
+	list, cnt := server.GetTunnel(start, length, taskType, clientId)
 	s.AjaxTable(list, cnt, cnt)
 }
 
@@ -72,22 +72,26 @@ func (s *IndexController) Add() {
 		s.SetInfo("新增")
 		s.display()
 	} else {
-		t := &utils.ServerConfig{
-			TcpPort:      s.GetIntNoErr("port"),
-			Mode:         s.GetString("type"),
-			Target:       s.GetString("target"),
-			U:            s.GetString("u"),
-			P:            s.GetString("p"),
-			Compress:     s.GetString("compress"),
-			Crypt:        s.GetBoolNoErr("crypt"),
-			Mux:          s.GetBoolNoErr("mux"),
-			IsRun:        0,
+		t := &utils.Tunnel{
+			TcpPort: s.GetIntNoErr("port"),
+			Mode:    s.GetString("type"),
+			Target:  s.GetString("target"),
+			Config: &utils.Config{
+				U:        s.GetString("u"),
+				P:        s.GetString("p"),
+				Compress: s.GetString("compress"),
+				Crypt:    s.GetBoolNoErr("crypt"),
+				Mux:      s.GetBoolNoErr("mux"),
+			},
 			Id:           server.CsvDb.GetTaskId(),
-			ClientId:     s.GetIntNoErr("client_id"),
 			UseClientCnf: s.GetBoolNoErr("use_client"),
-			Start:        1,
+			Status:       true,
 			Remark:       s.GetString("remark"),
 		}
+		var err error
+		if t.Client, err = server.CsvDb.GetClient(s.GetIntNoErr("client_id")); err != nil {
+			s.AjaxErr(err.Error())
+		}
 		server.CsvDb.NewTask(t)
 		if err := server.AddTask(t); err != nil {
 			s.AjaxErr(err.Error())
@@ -115,12 +119,12 @@ func (s *IndexController) Edit() {
 			t.Mode = s.GetString("type")
 			t.Target = s.GetString("target")
 			t.Id = id
-			t.ClientId = s.GetIntNoErr("client_id")
-			t.U = s.GetString("u")
-			t.P = s.GetString("p")
-			t.Compress = s.GetString("compress")
-			t.Crypt = s.GetBoolNoErr("crypt")
-			t.Mux = s.GetBoolNoErr("mux")
+			t.Client.Id = s.GetIntNoErr("client_id")
+			t.Config.U = s.GetString("u")
+			t.Config.P = s.GetString("p")
+			t.Config.Compress = s.GetString("compress")
+			t.Config.Crypt = s.GetBoolNoErr("crypt")
+			t.Config.Mux = s.GetBoolNoErr("mux")
 			t.UseClientCnf = s.GetBoolNoErr("use_client")
 			t.Remark = s.GetString("remark")
 			server.CsvDb.UpdateTask(t)
@@ -162,7 +166,7 @@ func (s *IndexController) HostList() {
 	} else {
 		start, length := s.GetAjaxParams()
 		clientId := s.GetIntNoErr("client_id")
-		list, cnt := server.CsvDb.GetHostList(start, length, clientId)
+		list, cnt := server.CsvDb.GetHost(start, length, clientId)
 		s.AjaxTable(list, cnt, cnt)
 	}
 }
@@ -182,8 +186,10 @@ func (s *IndexController) AddHost() {
 		s.SetInfo("新增")
 		s.display("index/hadd")
 	} else {
-		h := &utils.HostList{
-			ClientId:     s.GetIntNoErr("client_id"),
+		h := &utils.Host{
+			Client: &utils.Client{
+				Id: s.GetIntNoErr("client_id"),
+			},
 			Host:         s.GetString("host"),
 			Target:       s.GetString("target"),
 			HeaderChange: s.GetString("header"),
@@ -199,7 +205,7 @@ func (s *IndexController) EditHost() {
 	host := s.GetString("host")
 	if s.Ctx.Request.Method == "GET" {
 		s.Data["menu"] = "host"
-		if h, _, err := server.GetKeyByHost(host); err != nil {
+		if h, err := server.GetInfoByHost(host); err != nil {
 			s.error()
 		} else {
 			s.Data["h"] = h
@@ -207,10 +213,10 @@ func (s *IndexController) EditHost() {
 		s.SetInfo("修改")
 		s.display("index/hedit")
 	} else {
-		if h, _, err := server.GetKeyByHost(host); err != nil {
+		if h, err := server.GetInfoByHost(host); err != nil {
 			s.error()
 		} else {
-			h.ClientId = s.GetIntNoErr("client_id")
+			h.Client.Id = s.GetIntNoErr("client_id")
 			h.Host = s.GetString("nhost")
 			h.Target = s.GetString("target")
 			h.HeaderChange = s.GetString("header")
diff --git a/web/views/index/edit.html b/web/views/index/edit.html
index 176902d..e3865cf 100755
--- a/web/views/index/edit.html
+++ b/web/views/index/edit.html
@@ -31,7 +31,7 @@
                     </div>
                     <div class="form-group" id="client_id">
                         <label class="control-label">客户端ID</label>
-                        <input class="form-control" value="{{.t.ClientId}}" type="text" name="client_id"
+                        <input class="form-control" value="{{.t.Client.Id}}" type="text" name="client_id"
                                placeholder="客户端id">
                     </div>
                     <div class="form-group" id="use_client">
@@ -44,32 +44,32 @@
                     <div class="form-group" id="compress">
                         <label class="control-label">数据压缩方式(所有模式均支持)</label>
                         <select class="form-control" name="compress">
-                            <option {{if eq "" .t.Compress}}selected{{end}} value="">不压缩</option>
-                            <option {{if eq "snappy" .t.Compress}}selected{{end}} value="snappy">snappy压缩</option>
+                            <option {{if eq "" .t.Config.Compress}}selected{{end}} value="">不压缩</option>
+                            <option {{if eq "snappy" .t.Config.Compress}}selected{{end}} value="snappy">snappy压缩</option>
                         </select>
                     </div>
                     <div class="form-group" id="crypt">
                         <label class="control-label">是否加密传输(所有模式均支持)</label>
                         <select class="form-control" name="crypt">
-                            <option {{if eq false .t.Crypt}}selected{{end}} value="0">不加密</option>
-                            <option {{if eq  true .t.Crypt}}selected{{end}} value="1">加密</option>
+                            <option {{if eq false .t.Config.Crypt}}selected{{end}} value="0">不加密</option>
+                            <option {{if eq  true .t.Config.Crypt}}selected{{end}} value="1">加密</option>
                         </select>
                     </div>
                     <div class="form-group" id="mux">
                         <label class="control-label">是否启用TCP复用(所有模式均支持)</label>
                         <select class="form-control" name="mux">
-                            <option {{if eq false .t.Mux}}selected{{end}} value="0">不启用</option>
-                            <option {{if eq  true .t.Mux}}selected{{end}} value="1">启用</option>
+                            <option {{if eq false .t.Config.Mux}}selected{{end}} value="0">不启用</option>
+                            <option {{if eq  true .t.Config.Mux}}selected{{end}} value="1">启用</option>
                         </select>
                     </div>
                     <div class="form-group" id="u">
                         <label class="control-label">验证用户名(仅socks5,web穿透支持)</label>
-                        <input class="form-control" value="{{.t.U}}" type="text" name="u"
+                        <input class="form-control" value="{{.t.Config.U}}" type="text" name="u"
                                placeholder="不填则无需验证">
                     </div>
                     <div class="form-group" id="p">
                         <label class="control-label">验证密码(仅socks5,web穿透支持)</label>
-                        <input class="form-control" value="{{.t.P}}" type="text" name="p"
+                        <input class="form-control" value="{{.t.Config.P}}" type="text" name="p"
                                placeholder="不填则无需验证">
                     </div>
                 </form>
diff --git a/web/views/index/hedit.html b/web/views/index/hedit.html
index 2f2704e..d9d83ed 100644
--- a/web/views/index/hedit.html
+++ b/web/views/index/hedit.html
@@ -15,7 +15,7 @@
                     </div>
                     <div class="form-group">
                         <label class="control-label">客户端id</label>
-                        <input class="form-control" value="{{.h.ClientId}}" type="text" name="client_id"
+                        <input class="form-control" value="{{.h.Client.Id}}" type="text" name="client_id"
                                placeholder="客户端id">
                     </div>
                     <div class="form-group">
diff --git a/web/views/index/hlist.html b/web/views/index/hlist.html
index 6e42ae1..ce383e2 100755
--- a/web/views/index/hlist.html
+++ b/web/views/index/hlist.html
@@ -10,6 +10,11 @@
                         <th>host</th>
                         <th>内网目标</th>
                         <th>host改写</th>
+                        <th>压缩方式</th>
+                        <th>加密</th>
+                        <th>多路复用</th>
+                        <th>用户名</th>
+                        <th>密码</th>
                         <th>出口流量</th>
                         <th>入口流量</th>
                         <th>操作</th>
@@ -68,13 +73,18 @@
             },
             dom: '<"top"fl><"toolbar">rt<"bottom"ip><"clear">',
             columns: [ //这个是显示到界面上的个数据 格式为 {data:'显示的字段名'}
-                {data: 'ClientId'},
+                {data: 'Remark'},
                 {data: 'Remark'},
                 {data: 'Host'},
                 {data: 'Target'},
                 {data: 'HostChange'},
                 {data: 'HostChange'},
                 {data: 'HostChange'},
+                {data: 'HostChange'},
+                {data: 'HostChange'},
+                {data: 'HostChange'},
+                {data: 'HostChange'},
+                {data: 'HostChange'},
                 {data: 'Target'},
             ],
             bFilter: false,
@@ -88,6 +98,12 @@
                             + ' </div>'
                 }
             },
+                {
+                    targets: 1,
+                    render: function (data, type, row, meta) {
+                        return row.Client.Id
+                    }
+                },
                 {
                     targets: -2,
                     render: function (data, type, row, meta) {
@@ -99,6 +115,46 @@
                     render: function (data, type, row, meta) {
                         return change(row.Flow.ExportFlow)
                     }
+                },
+                {
+                    targets: -4,
+                    render: function (data, type, row, meta) {
+                        return row.Client.Cnf.P
+                    }
+                },
+                {
+                    targets: -5,
+                    render: function (data, type, row, meta) {
+                        return row.Client.Cnf.U
+                    }
+                },
+                {
+                    targets: -6,
+                    render: function (data, type, row, meta) {
+                        if (row.Client.Cnf.Mux == "0") {
+                            return "不启用"
+                        } else {
+                            return "启用"
+                        }
+                    }
+                }
+                ,
+                {
+                    targets: -7,
+                    render: function (data, type, row, meta) {
+                        if (row.Client.Cnf.Crypt == "0") {
+                            return "不加密"
+                        } else {
+                            return "加密"
+                        }
+                    }
+                }
+                ,
+                {
+                    targets: -8,
+                    render: function (data, type, row, meta) {
+                        return row.Client.Cnf.Compress
+                    }
                 }
             ],
             buttons: []
diff --git a/web/views/index/list.html b/web/views/index/list.html
index 498cd6a..5a8fd56 100755
--- a/web/views/index/list.html
+++ b/web/views/index/list.html
@@ -102,7 +102,7 @@
             autoWidth: false,
             ordering: false,
             ajax: {
-                url: '/index/getserverconfig?type={{.type}}' + "&client_id=" +{{.client_id}},
+                url: '/index/gettunnel?type={{.type}}' + "&client_id=" +{{.client_id}},
                 type: 'POST'
             },
             dom: '<"top"fl><"toolbar">rt<"bottom"ip><"clear">',
@@ -118,7 +118,7 @@
                 {data: 'U'},
                 {data: 'P'},
                 {data: 'ClientStatus'},
-                {data: 'IsRun'},
+                {data: 'Status'},
                 {data: 'ExportFlow'},
                 {data: 'InletFlow'},
                 {data: "Id"}
@@ -127,7 +127,7 @@
             columnDefs: [{
                 targets: -1,
                 render: function (data, type, row, meta) {
-                    if (row.IsRun == 1) {
+                    if (row.Status == 1) {
                         btn = "<button onclick=\"stop('" + row.Id + "')\" class=\"btn btn-secondary btn-sm\" type=\"button\">关闭</button>"
                     } else {
                         btn = "<button onclick=\"start('" + row.Id + "')\" class=\"btn btn-success btn-sm\" type=\"button\">打开</button>"
@@ -137,11 +137,43 @@
                             '<button onclick="del(\'' + row.Id + '\')" type="button"   class="btn btn-danger btn-sm">删除</button>' +
                             btn_edit + btn + ' </div>'
                 }
+            }, {
+                targets: 2,
+                render: function (data, type, row, meta) {
+                    return row.Client.Id
+                }
+            }, {
+                targets: 5,
+                render: function (data, type, row, meta) {
+                    if (row.UseClientCnf == true) {
+                        return row.Client.Cnf.Compress
+                    } else {
+                        return row.Config.Compress
+                    }
+                }
+            }, {
+                targets: 8,
+                render: function (data, type, row, meta) {
+                    if (row.UseClientCnf == true) {
+                        return row.Client.Cnf.U
+                    } else {
+                        return row.Config.U
+                    }
+                }
+            }, {
+                targets: 9,
+                render: function (data, type, row, meta) {
+                    if (row.UseClientCnf == true) {
+                        return row.Client.Cnf.P
+                    } else {
+                        return row.Config.P
+                    }
+                }
             },
                 {
                     targets: -4,
                     render: function (data, type, row, meta) {
-                        if (data == 0) {
+                        if (data == false) {
                             return "<span class=\"badge badge-pill badge-secondary\">暂停</span>"
                         } else {
                             return "<span class=\"badge badge-pill badge-success\">正常</span>"
@@ -151,7 +183,12 @@
                 {
                     targets: -9,
                     render: function (data, type, row, meta) {
-                        if (data == "0") {
+                        if (row.UseClientCnf == true) {
+                            crypt = row.Client.Cnf.Crypt
+                        } else {
+                            crypt = row.Config.Crypt
+                        }
+                        if (crypt == "0") {
                             return "不加密"
                         } else {
                             return "加密"
@@ -161,7 +198,12 @@
                 {
                     targets: -8,
                     render: function (data, type, row, meta) {
-                        if (data == "0") {
+                        if (row.UseClientCnf == true) {
+                            mux = row.Client.Cnf.Mux
+                        } else {
+                            mux = row.Config.Mux
+                        }
+                        if (mux == "0") {
                             return "不启用"
                         } else {
                             return "启用"
@@ -171,7 +213,7 @@
                 {
                     targets: -5,
                     render: function (data, type, row, meta) {
-                        if (data == 0) {
+                        if (row.Client.IsConnect == false) {
                             return "<span class=\"badge badge-pill badge-secondary\">离线</span>"
                         } else {
                             return "<span class=\"badge badge-pill badge-success\">在线</span>"