luasocket icon indicating copy to clipboard operation
luasocket copied to clipboard

How can use accept() again after connection closed by remote client.

Open nizqsut opened this issue 7 years ago • 2 comments

For this demo: receiving a line from remote client and sent it back. My issue is: After connection closed by remote client, I try to call accept() again and always return "closed". And remote client try to connect to the server and always meets "Connection Refused Socket Error # 10061".

Here is the demo code:

require "socket"

local port =  9999

local srv = socket.tcp()
srv:bind('*', port)
srv:settimeout(30)
srv:setoption('reuseaddr', true)
srv:listen(10)

while true do

	local cli, msg = srv:accept()
	if msg then
		-- Trace 2: after remote closed, accept() always return fail.
		-- How can it using accept() again?
		print("error: " .. msg)
	else
		print("Connected...")
		srv:close()
		while true do
			local cmd, msg = cli:receive()
			if msg then
				-- Trace 1: closed by remote client, run to there
				print("receive error: " .. msg)
				cli:close()
				break
			else
				print("cmd: " .. cmd)
				cli:send(cmd)
				cli:send("\r\n")
			end
		end
	end
end

nizqsut avatar Nov 02 '17 02:11 nizqsut

I figure out a solution: use a new server and bind again. I was wondering that there is any better way.

Here is the new code:

require "socket"

local port =  9999



while true do
	local srv = socket.tcp()
	srv:bind('*', port)
	srv:settimeout(30)
	srv:setoption('reuseaddr', true)
	srv:listen(10)

	local cli, msg = srv:accept()
	if msg then
		-- Trace 2: after remote closed, accept() always return fail.
		-- How can it using accept() again?
		print("error: " .. msg)
	else
		print("Connected...")
		srv:close()
		while true do
			local cmd, msg = cli:receive()
			if msg then
				-- Trace 1: closed by remote client, run to there
				print("receive error: " .. msg)
				cli:close()
				break
			else
				print("cmd: " .. cmd)
				cli:send(cmd)
				cli:send("\r\n")
			end
		end
	end
end

nizqsut avatar Nov 02 '17 02:11 nizqsut

Your first code was essentially right. Just remove the srv:close() in the loop, because that's what's causing subsequent connections to fail. The server socket needs to remain open and listening while handling accepted clients.

ewestbrook avatar Feb 16 '19 14:02 ewestbrook

Besides apparently being resolved, #81 brought a little more tooling to the table for detecting this situation in the first place.

alerque avatar Nov 10 '23 21:11 alerque