class Async::IO::TCPSocket

Asynchronous TCP socket wrapper.

def close

def close
	@stream.flush
	super
end

def initialize(remote_host, remote_port = nil, local_host = nil, local_port = nil)

def initialize(remote_host, remote_port = nil, local_host = nil, local_port = nil)
	if remote_host.is_a? ::TCPSocket
		super(remote_host)
	else
		remote_address = Addrinfo.tcp(remote_host, remote_port)
		local_address = Addrinfo.tcp(local_host, local_port) if local_host
		
		# We do this unusual dance to avoid leaking an "open" socket instance.
		socket = Socket.connect(remote_address, local_address: local_address)
		fd = socket.fcntl(Fcntl::F_DUPFD)
		Async.logger.debug(self) {"Connected to #{remote_address.inspect}: #{fd}"}
		socket.close
		
		super(::TCPSocket.for_fd(fd))
		
		# The equivalent blocking operation. Unfortunately there is no trivial way to make this non-blocking.
		# super(::TCPSocket.new(remote_host, remote_port, local_host, local_port))
	end
	
	@stream = Stream.new(self)
end

def sysread(size, buffer = nil)

def sysread(size, buffer = nil)
	data = @stream.read_partial(size)
	
	if buffer
		buffer.replace(data)
	end
	
	return data
end