@@ -62,6 +62,25 @@ public extension AsyncSocketPool where Self == SocketPool<Poll> {
6262
6363public struct AsyncSocket : Sendable {
6464
65+ public struct Message : Sendable {
66+ public let peerAddress : sockaddr_storage
67+ public let bytes : [ UInt8 ]
68+ public let interfaceIndex : UInt32 ?
69+ public let localAddress : sockaddr_storage ?
70+
71+ public init (
72+ peerAddress: sockaddr_storage ,
73+ bytes: [ UInt8 ] ,
74+ interfaceIndex: UInt32 ? = nil ,
75+ localAddress: sockaddr_storage ? = nil
76+ ) {
77+ self . peerAddress = peerAddress
78+ self . bytes = bytes
79+ self . interfaceIndex = interfaceIndex
80+ self . localAddress = localAddress
81+ }
82+ }
83+
6584 public let socket : Socket
6685 let pool : any AsyncSocketPool
6786
@@ -143,6 +162,23 @@ public struct AsyncSocket: Sendable {
143162 } while true
144163 }
145164
165+ #if !canImport(WinSDK)
166+ public func receive( atMost length: Int ) async throws -> Message {
167+ try Task . checkCancellation ( )
168+
169+ repeat {
170+ do {
171+ let ( peerAddress, bytes, interfaceIndex, localAddress) = try socket. receive ( length: length)
172+ return Message ( peerAddress: peerAddress, bytes: bytes, interfaceIndex: interfaceIndex, localAddress: localAddress)
173+ } catch SocketError . blocked {
174+ try await pool. suspendSocket ( socket, untilReadyFor: . read)
175+ } catch {
176+ throw error
177+ }
178+ } while true
179+ }
180+ #endif
181+
146182 /// Reads bytes from the socket up to by not over/
147183 /// - Parameter bytes: The max number of bytes to read
148184 /// - Returns: an array of the read bytes capped to the number of bytes provided.
@@ -190,6 +226,31 @@ public struct AsyncSocket: Sendable {
190226 try await send ( Array ( data) , to: address)
191227 }
192228
229+ #if !canImport(WinSDK)
230+ public func send(
231+ message: [ UInt8 ] ,
232+ to peerAddress: some SocketAddress ,
233+ interfaceIndex: UInt32 ? = nil ,
234+ from localAddress: ( some SocketAddress ) ? = nil
235+ ) async throws {
236+ let sent = try await pool. loopUntilReady ( for: . write, on: socket) {
237+ try socket. send ( message: message, to: peerAddress, interfaceIndex: interfaceIndex, from: localAddress)
238+ }
239+ guard sent == message. count else {
240+ throw SocketError . disconnected
241+ }
242+ }
243+
244+ public func send(
245+ message: Data ,
246+ to peerAddress: some SocketAddress ,
247+ interfaceIndex: UInt32 ? = nil ,
248+ from localAddress: ( some SocketAddress ) ? = nil
249+ ) async throws {
250+ try await send ( message: Array ( message) , to: peerAddress, interfaceIndex: interfaceIndex, from: localAddress)
251+ }
252+ #endif
253+
193254 public func close( ) throws {
194255 try socket. close ( )
195256 }
@@ -275,7 +336,8 @@ public struct AsyncSocketSequence: AsyncSequence, AsyncIteratorProtocol, Sendabl
275336public struct AsyncSocketMessageSequence : AsyncSequence , AsyncIteratorProtocol , Sendable {
276337 public static let DefaultMaxMessageLength : Int = 1500
277338
278- public typealias Element = ( sockaddr_storage , [ UInt8 ] )
339+ // Windows has a different recvmsg() API signature which is presently unsupported
340+ public typealias Element = AsyncSocket . Message
279341
280342 private let socket : AsyncSocket
281343 private let maxMessageLength : Int
@@ -288,7 +350,15 @@ public struct AsyncSocketMessageSequence: AsyncSequence, AsyncIteratorProtocol,
288350 }
289351
290352 public mutating func next( ) async throws -> Element ? {
291- return try await socket. receive ( atMost: maxMessageLength)
353+ #if !canImport(WinSDK)
354+ try await socket. receive ( atMost: maxMessageLength)
355+ #else
356+ let peerAddress : sockaddr_storage
357+ let bytes : [ UInt8 ]
358+
359+ ( peerAddress, bytes) = try await socket. receive ( atMost: maxMessageLength)
360+ return AsyncSocket . Message ( peerAddress: peerAddress, bytes: bytes)
361+ #endif
292362 }
293363}
294364
0 commit comments