diff --git a/lualib/http/httpc.lua b/lualib/http/httpc.lua index 615d6017..33f3eee4 100644 --- a/lualib/http/httpc.lua +++ b/lualib/http/httpc.lua @@ -104,17 +104,13 @@ function httpc.request(method, host, url, recvheader, header, content) if timeout then skynet.timeout(timeout, function() if not finish then - local temp = fd - fd = nil - socket.shutdown(temp) + socket.shutdown(fd) -- shutdown the socket fd, need close later. end end) end local ok , statuscode, body = pcall(request, fd,method, host, url, recvheader, header, content) finish = true - if fd then -- may close by skynet.timeout - socket.close(fd) - end + socket.close(fd) if ok then return statuscode, body else diff --git a/lualib/skynet/socket.lua b/lualib/skynet/socket.lua index 26524d90..357e780f 100644 --- a/lualib/skynet/socket.lua +++ b/lualib/skynet/socket.lua @@ -209,22 +209,15 @@ function socket.start(id, func) return connect(id, func) end -local function close_fd(id, func) +function socket.shutdown(id) local s = socket_pool[id] if s then - if s.buffer then - driver.clear(s.buffer,buffer_pool) - end - if s.connected then - func(id) - end + driver.clear(s.buffer,buffer_pool) + -- the framework would send SKYNET_SOCKET_TYPE_CLOSE , need close(id) later + driver.shutdown(id) end end -function socket.shutdown(id) - close_fd(id, driver.shutdown) -end - function socket.close_fd(id) assert(socket_pool[id] == nil,"Use socket.close instead") driver.close(id) @@ -250,7 +243,7 @@ function socket.close(id) end s.connected = false end - close_fd(id) -- clear the buffer (already close fd) + driver.clear(s.buffer,buffer_pool) assert(s.lock == nil or next(s.lock) == nil) socket_pool[id] = nil end @@ -352,6 +345,13 @@ function socket.invalid(id) return socket_pool[id] == nil end +function socket.disconnected(id) + local s = socket_pool[id] + if s then + return not(s.connected or s.connecting) + end +end + function socket.listen(host, port, backlog) if port == nil then host, port = string.match(host, "([^:]+):(.+)$") @@ -392,10 +392,12 @@ end -- you must call socket.start(id) later in other service function socket.abandon(id) local s = socket_pool[id] - if s and s.buffer then + if s then driver.clear(s.buffer,buffer_pool) + s.connected = false + wakeup(s) + socket_pool[id] = nil end - socket_pool[id] = nil end function socket.limit(id, limit) diff --git a/lualib/skynet/socketchannel.lua b/lualib/skynet/socketchannel.lua index a6474a81..67c2f1d5 100644 --- a/lualib/skynet/socketchannel.lua +++ b/lualib/skynet/socketchannel.lua @@ -289,6 +289,12 @@ end local function check_connection(self) if self.__sock then + if socket.disconnected(self.__sock[1]) then + -- closed by peer + skynet.error("socket: disconnect detected ", self.__host, self.__port) + close_channel_socket(self) + return + end local authco = self.__authcoroutine if not authco then return true