@@ -192,7 +192,54 @@ public actor SQLClient {
192192
193193 // MARK: - Synchronous Helpers
194194
195+ private nonisolated func checkReachability( server: String , port: UInt16 ) throws {
196+ let host = CFHostCreateWithName ( nil , server as CFString ) . takeRetainedValue ( )
197+ var error = CFStreamError ( )
198+ CFHostStartInfoResolution ( host, . addresses, & error)
199+
200+ guard error. error == 0 else {
201+ throw SQLClientError . connectionFailed ( server: server)
202+ }
203+
204+ // Attempt a TCP connection with a 5 second timeout
205+ var readStream : Unmanaged < CFReadStream > ?
206+ var writeStream : Unmanaged < CFWriteStream > ?
207+ CFStreamCreatePairWithSocketToHost ( nil , server as CFString , UInt32 ( port) , & readStream, & writeStream)
208+
209+ guard let read = readStream? . takeRetainedValue ( ) ,
210+ let write = writeStream? . takeRetainedValue ( ) else {
211+ throw SQLClientError . connectionFailed ( server: server)
212+ }
213+
214+ CFReadStreamOpen ( read)
215+ CFWriteStreamOpen ( write)
216+
217+ let deadline = Date ( ) . addingTimeInterval ( 5 )
218+ var connected = false
219+
220+ while Date ( ) < deadline {
221+ let readStatus = CFReadStreamGetStatus ( read)
222+ let writeStatus = CFWriteStreamGetStatus ( write)
223+ if readStatus == . open && writeStatus == . open {
224+ connected = true
225+ break
226+ }
227+ Thread . sleep ( forTimeInterval: 0.1 )
228+ }
229+
230+ CFReadStreamClose ( read)
231+ CFWriteStreamClose ( write)
232+
233+ guard connected else {
234+ throw SQLClientError . connectionFailed ( server: server)
235+ }
236+ }
237+
195238 private nonisolated func _connectSync( options: SQLClientConnectionOptions ) throws -> ( login: TDSHandle , connection: TDSHandle ) {
239+ // Pre-flight — fail fast if the server isn't reachable at the TCP level.
240+ // Default port for SQL Server is 1433.
241+ try checkReachability ( server: options. server, port: options. port ?? 1433 )
242+
196243 dbinit ( )
197244 dberrhandle ( SQLClient_errorHandler)
198245 dbmsghandle ( SQLClient_messageHandler)
0 commit comments