77
88import Foundation
99
10+ #if os(Windows)
11+ import WinSDK
12+ #endif
13+
14+ #if os(Windows)
15+ public typealias PlatformSocketFD = SOCKET
16+ public let invalidPlatformSocketFD = INVALID_SOCKET
17+ #else
18+ public typealias PlatformSocketFD = Int32
19+ public let invalidPlatformSocketFD = Int32 ( - 1 )
20+ #endif
21+
1022public enum SocketError : Error {
1123 case socketCreationFailed( String )
1224 case socketSettingReUseAddrFailed( String )
@@ -23,11 +35,10 @@ public enum SocketError: Error {
2335
2436// swiftlint: disable identifier_name
2537open class Socket : Hashable , Equatable {
26-
27- let socketFileDescriptor : Int32
38+ let socketFileDescriptor : PlatformSocketFD
2839 private var shutdown = false
2940
30- public init ( socketFileDescriptor: Int32 ) {
41+ public init ( socketFileDescriptor: PlatformSocketFD ) {
3142 self . socketFileDescriptor = socketFileDescriptor
3243 }
3344
@@ -55,7 +66,7 @@ open class Socket: Hashable, Equatable {
5566 throw SocketError . getSockNameFailed ( Errno . description ( ) )
5667 }
5768 let sin_port = pointer. pointee. sin_port
58- #if os(Linux)
69+ #if os(Linux) || os(Windows)
5970 return ntohs ( sin_port)
6071 #else
6172 return Int ( OSHostByteOrder ( ) ) != OSLittleEndian ? sin_port. littleEndian : sin_port. bigEndian
@@ -112,6 +123,8 @@ open class Socket: Hashable, Equatable {
112123 while sent < length {
113124 #if os(Linux)
114125 let result = send ( self . socketFileDescriptor, pointer + sent, Int ( length - sent) , Int32 ( MSG_NOSIGNAL) )
126+ #elseif os(Windows)
127+ let result = Int ( send ( self . socketFileDescriptor, pointer + sent, Int32 ( length - sent) , 0 ) )
115128 #else
116129 let result = write ( self . socketFileDescriptor, pointer + sent, Int ( length - sent) )
117130 #endif
@@ -133,6 +146,8 @@ open class Socket: Hashable, Equatable {
133146
134147 #if os(Linux)
135148 let count = Glibc . read ( self . socketFileDescriptor as Int32 , & byte, 1 )
149+ #elseif os(Windows)
150+ let count = recv ( self . socketFileDescriptor, & byte, 1 , 0 )
136151 #else
137152 let count = Darwin . read ( self . socketFileDescriptor as Int32 , & byte, 1 )
138153 #endif
@@ -172,6 +187,8 @@ open class Socket: Hashable, Equatable {
172187
173188 #if os(Linux)
174189 let bytesRead = Glibc . read ( self . socketFileDescriptor as Int32 , baseAddress + offset, readLength)
190+ #elseif os(Windows)
191+ let bytesRead = Int ( recv ( self . socketFileDescriptor, baseAddress + offset, Int32 ( readLength) , 0 ) )
175192 #else
176193 let bytesRead = Darwin . read ( self . socketFileDescriptor as Int32 , baseAddress + offset, readLength)
177194 #endif
@@ -205,14 +222,19 @@ open class Socket: Hashable, Equatable {
205222 throw SocketError . getPeerNameFailed ( Errno . description ( ) )
206223 }
207224 var hostBuffer = [ CChar] ( repeating: 0 , count: Int ( NI_MAXHOST) )
208- if getnameinfo ( & addr, len, & hostBuffer, socklen_t ( hostBuffer. count) , nil , 0 , NI_NUMERICHOST) != 0 {
225+ #if os(Windows)
226+ let hostBufferSize = DWORD ( hostBuffer. count)
227+ #else
228+ let hostBufferSize = socklen_t ( hostBuffer. count)
229+ #endif
230+ if getnameinfo ( & addr, len, & hostBuffer, hostBufferSize, nil , 0 , NI_NUMERICHOST) != 0 {
209231 throw SocketError . getNameInfoFailed ( Errno . description ( ) )
210232 }
211233 return String ( cString: hostBuffer)
212234 }
213235
214- public class func setNoSigPipe( _ socket: Int32 ) {
215- #if os(Linux)
236+ public class func setNoSigPipe( _ socket: PlatformSocketFD ) {
237+ #if os(Linux) || os(Windows)
216238 // There is no SO_NOSIGPIPE in Linux (nor some other systems). You can instead use the MSG_NOSIGNAL flag when calling send(),
217239 // or use signal(SIGPIPE, SIG_IGN) to make your entire application ignore SIGPIPE.
218240 #else
@@ -222,9 +244,11 @@ open class Socket: Hashable, Equatable {
222244 #endif
223245 }
224246
225- public class func close( _ socket: Int32 ) {
247+ public class func close( _ socket: PlatformSocketFD ) {
226248 #if os(Linux)
227249 _ = Glibc . close ( socket)
250+ #elseif os(Windows)
251+ _ = closesocket ( socket)
228252 #else
229253 _ = Darwin . close ( socket)
230254 #endif
0 commit comments