diff --git a/adb/adb.cpp b/adb/adb.cpp
index 0181daa60a17592a69ba82c6771e8ea250872683..55c64ec4e883199f9fd319327991e0717b5b3f11 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -1054,15 +1054,12 @@ int handle_host_request(const char* service, TransportType type,
     if (strcmp(service, "kill") == 0) {
         fprintf(stderr, "adb server killed by remote request\n");
         fflush(stdout);
-        SendOkay(reply_fd);
 
-        // On Windows, if the process exits with open sockets that
-        // shutdown(SD_SEND) has not been called on, TCP RST segments will be
-        // sent to the peers which will cause their next recv() to error-out
-        // with WSAECONNRESET. In the case of this code, that means the client
-        // may not read the OKAY sent above.
-        adb_shutdown(reply_fd);
+        // Send a reply even though we don't read it anymore, so that old versions
+        // of adb that do read it don't spew error messages.
+        SendOkay(reply_fd);
 
+        // Rely on process exit to close the socket for us.
         android::base::quick_exit(0);
     }
 
diff --git a/adb/adb_client.cpp b/adb/adb_client.cpp
index 4f3ff25dfcacde58abcc1cbf55e1ef519ab35c08..f5d0f02df59bbef160df4c47c19414e5d76bd4ed 100644
--- a/adb/adb_client.cpp
+++ b/adb/adb_client.cpp
@@ -123,7 +123,7 @@ bool adb_status(int fd, std::string* error) {
     return false;
 }
 
-int _adb_connect(const std::string& service, std::string* error) {
+static int _adb_connect(const std::string& service, std::string* error) {
     D("_adb_connect: %s", service.c_str());
     if (service.empty() || service.size() > MAX_PAYLOAD_V1) {
         *error = android::base::StringPrintf("bad service name length (%zd)",
@@ -158,6 +158,25 @@ int _adb_connect(const std::string& service, std::string* error) {
     return fd;
 }
 
+bool adb_kill_server() {
+    D("adb_kill_server");
+    std::string reason;
+    int fd = socket_spec_connect(__adb_server_socket_spec, &reason);
+    if (fd < 0) {
+        fprintf(stderr, "cannot connect to daemon at %s: %s\n", __adb_server_socket_spec,
+                reason.c_str());
+        return true;
+    }
+
+    if (!SendProtocolString(fd, "host:kill")) {
+        fprintf(stderr, "error: write failure during connection: %s\n", strerror(errno));
+        return false;
+    }
+
+    ReadOrderlyShutdown(fd);
+    return true;
+}
+
 int adb_connect(const std::string& service, std::string* error) {
     // first query the adb server's version
     int fd = _adb_connect("host:version", error);
@@ -214,18 +233,7 @@ int adb_connect(const std::string& service, std::string* error) {
         if (version != ADB_SERVER_VERSION) {
             fprintf(stderr, "adb server version (%d) doesn't match this client (%d); killing...\n",
                     version, ADB_SERVER_VERSION);
-            fd = _adb_connect("host:kill", error);
-            if (fd >= 0) {
-                ReadOrderlyShutdown(fd);
-                adb_close(fd);
-            } else {
-                // If we couldn't connect to the server or had some other error,
-                // report it, but still try to start the server.
-                fprintf(stderr, "error: %s\n", error->c_str());
-            }
-
-            /* XXX can we better detect its death? */
-            std::this_thread::sleep_for(2s);
+            adb_kill_server();
             goto start_server;
         }
     }
diff --git a/adb/adb_client.h b/adb/adb_client.h
index d07c1e96bc1c886dd6e75e1fd5e64a0127fe0a43..fabec0050ffcf888f1b5d74e9ca3d0a2c404b4e3 100644
--- a/adb/adb_client.h
+++ b/adb/adb_client.h
@@ -26,7 +26,9 @@
 // Connect to adb, connect to the named service, and return a valid fd for
 // interacting with that service upon success or a negative number on failure.
 int adb_connect(const std::string& service, std::string* _Nonnull error);
-int _adb_connect(const std::string& service, std::string* _Nonnull error);
+
+// Kill the currently running adb server, if it exists.
+bool adb_kill_server();
 
 // Connect to adb, connect to the named service, returns true if the connection
 // succeeded AND the service returned OKAY. Outputs any returned error otherwise.
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index a9b1540d5a20361126419764d868513a6042e44a..f49c69dafdc58161afbdfb5b4830b0a868dd8b52 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -1546,25 +1546,7 @@ int adb_commandline(int argc, const char** argv) {
         return 0;
     }
     else if (!strcmp(argv[0], "kill-server")) {
-        std::string error;
-        int fd = _adb_connect("host:kill", &error);
-        if (fd == -2) {
-            // Failed to make network connection to server. Don't output the
-            // network error since that is expected.
-            fprintf(stderr,"* server not running *\n");
-            // Successful exit code because the server is already "killed".
-            return 0;
-        } else if (fd == -1) {
-            // Some other error.
-            fprintf(stderr, "error: %s\n", error.c_str());
-            return 1;
-        } else {
-            // Successfully connected, kill command sent, okay status came back.
-            // Server should exit() in a moment, if not already.
-            ReadOrderlyShutdown(fd);
-            adb_close(fd);
-            return 0;
-        }
+        return adb_kill_server() ? 0 : 1;
     }
     else if (!strcmp(argv[0], "sideload")) {
         if (argc != 2) return syntax_error("sideload requires an argument");