diff --git a/client/client.cpp b/client/client.cpp
index af5c1a7..20cdf53 100644
--- a/client/client.cpp
+++ b/client/client.cpp
@@ -17,7 +17,7 @@ CClient::~CClient()
 {
     th_run_ = false;
     sleep_.contiune();
-    if (down_->file_) {
+    if (down_ && down_->file_) {
         fclose(down_->file_);
         down_->file_ = nullptr;
     }
@@ -31,7 +31,6 @@ CClient::~CClient()
     if (hearts_.joinable()) {
         hearts_.join();
     }
-
     for (auto& item : ths_) {
         if (item.joinable()) {
             item.join();
@@ -425,7 +424,7 @@ void CClient::send_file_data_th(const char* keys)
             logger_->error("Stop Trans {} To {} failed.", t->cur_file_, str_key);
             return;
         }
-        // std::this_thread::sleep_for(std::chrono::milliseconds(10));
+        std::this_thread::sleep_for(std::chrono::milliseconds(10));
     }
 
     buf->type_ = TYPE_TRANS_DONE;
diff --git a/net/net_base.cpp b/net/net_base.cpp
index ec6bd13..6f7f2f5 100644
--- a/net/net_base.cpp
+++ b/net/net_base.cpp
@@ -16,6 +16,7 @@ bool CTcpClient::connect(const std::string& host, const std::string& port)
         asio::ip::tcp::resolver::results_type endpoints = resolver.resolve(host, port);
         asio::connect(socket_, endpoints);
         logger_->info("Connected to {}:{}", host, port);
+        is_normal_ = true;
         return true;
     } catch (const std::exception& ex) {
         logger_->error("Connection failed: {}", ex.what());
@@ -27,6 +28,7 @@ void CTcpClient::disconnect()
 {
     if (socket_.is_open()) {
         try {
+            socket_.shutdown(asio::ip::tcp::socket::shutdown_both);
             socket_.close();
             logger_->info("Disconnected.");
         } catch (const std::exception& ex) {
@@ -37,6 +39,10 @@ void CTcpClient::disconnect()
 
 bool CTcpClient::send(const char* data, int len)
 {
+    if (!is_normal_) {
+        logger_->error("abnormal state, will not send.");
+        return false;
+    }
     try {
         auto send_size = asio::write(socket_, asio::buffer(data, len));
         // logger_->info("Need Send len: {} Real Send len: {}", len, send_size);
@@ -56,11 +62,13 @@ void CTcpClient::async_recv()
 {
     auto self(shared_from_this());
     socket_.async_read_some(asio::buffer(tmp_buf_), [this, self](std::error_code ec, std::size_t length) {
-        // logger_->debug("{} {}", __FUNCTION__, ec.message());
         if (ec) {
-            if (ec == asio::error::eof) {
-                logger_->error("Remote Server Closed.");
+            is_normal_ = false;
+            if (ec.value() == 995) {
+                // 正常中止退出
+                return;
             }
+            logger_->error("{} {} error => {}", __FUNCTION__, ec.value(), ec.message());
         } else {
             buffer_.push(tmp_buf_.data(), length);
             while (true) {
diff --git a/net/net_base.h b/net/net_base.h
index cb330dd..afecc4d 100644
--- a/net/net_base.h
+++ b/net/net_base.h
@@ -28,4 +28,5 @@ private:
     std::array<char, g_BuffSize> tmp_buf_;
     ExFun_t fun_;
     std::string remote_key_;
+    bool is_normal_{true};
 };
\ No newline at end of file
diff --git a/server/server.cpp b/server/server.cpp
index dcd68a6..4aa1cc1 100644
--- a/server/server.cpp
+++ b/server/server.cpp
@@ -142,7 +142,7 @@ void CTcpServer::trans_data(CFrameBuffer* buf)
     case TYPE_OPEN_FILE:
     case TYPE_TRANS_DONE:
     case TYPE_TRANS_FILE: {
-        if (check_double(fcli, tcli, buf) && !send_frame(tcli->socket_, buf)) {
+        if (check_double(buf, fcli, tcli) && tcli && !send_frame(tcli->socket_, buf)) {
             logger_->error("Send from {} to {} failed Or One Offline.", buf->fid_, buf->tid_);
         }
         break;
@@ -153,21 +153,31 @@ void CTcpServer::trans_data(CFrameBuffer* buf)
     }
 }
 
-bool CTcpServer::check_double(std::shared_ptr<ClientCache>& fcli, std::shared_ptr<ClientCache>& tcli,
-                              CFrameBuffer* buf)
+bool CTcpServer::check_double(CFrameBuffer* buf, std::shared_ptr<ClientCache>& fcli,
+                              std::shared_ptr<ClientCache>& tcli)
 {
+    std::lock_guard<std::mutex> lock(cli_mut_);
+    if (client_map_.count(buf->fid_)) {
+        fcli = client_map_[buf->fid_];
+    }
+    if (client_map_.count(buf->tid_)) {
+        tcli = client_map_[buf->tid_];
+    }
     if (fcli == nullptr && tcli) {
         buf->type_ = TYPE_OFFLINE;
+        logger_->warn("A Notic {} That {} Offline.", buf->tid_, buf->fid_);
         send_frame(tcli->socket_, buf);
         return false;
     }
     if (tcli == nullptr && fcli) {
         std::swap(buf->fid_, buf->tid_);
         buf->type_ = TYPE_OFFLINE;
+        logger_->warn("B Notic {} That {} Offline.", buf->tid_, buf->fid_);
         send_frame(fcli->socket_, buf);
         return false;
     }
     if (tcli == nullptr && fcli == nullptr) {
+        logger_->warn("Both Offline.", buf->fid_, buf->tid_);
         return false;
     }
     return true;
@@ -265,7 +275,8 @@ bool CTcpServer::send_frame(std::shared_ptr<asio::ip::tcp::socket> socket, CFram
         return false;
     }
     if (!socket->send(asio::buffer(out_buf, out_len))) {
-        logger_->error("{} send failed.", __FUNCTION__);
+        logger_->error("{} send failed, buf type:{}, fid:{}, tid:{}", __FUNCTION__,
+                       static_cast<int>(buf->type_), buf->fid_, buf->tid_);
         delete[] out_buf;
         return false;
     }
diff --git a/server/server.h b/server/server.h
index 76f02b5..e4cfdc0 100644
--- a/server/server.h
+++ b/server/server.h
@@ -37,8 +37,8 @@ private:
 
 private:
     void trans_data(CFrameBuffer* buf);
-    bool check_double(std::shared_ptr<ClientCache>& fcli, std::shared_ptr<ClientCache>& tcli,
-                      CFrameBuffer* buf);
+    bool check_double(CFrameBuffer* buf, std::shared_ptr<ClientCache>& fcli,
+                      std::shared_ptr<ClientCache>& tcli);
 
 private:
     void accept_client();