Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
nizqsut opened this issue Nov 2, 2017 · 3 comments
Closed

Comments

@nizqsut
Copy link

nizqsut commented Nov 2, 2017

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
Copy link
Author

nizqsut commented Nov 2, 2017

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

@ewestbrook
Copy link
Contributor

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.

@alerque
Copy link
Member

alerque commented Nov 10, 2023

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

@alerque alerque closed this as completed Nov 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants