[swift-server-dev] Sockets API

Helge Heß me at helgehess.eu
Fri Oct 28 18:06:38 CDT 2016


On 28 Oct 2016, at 01:27, Michael Chiu via swift-server-dev <swift-server-dev at swift.org> wrote:
> On 27 Oct 2016, at 15:27:56 CDT 2016, Helge Heß <me at helgehess.eu> wrote:
> > I can see (and essentially agree) with your point, but then I’m also back at wondering why there is a need for a common socket API at _such_ a low level. 
> I think one of the reason why common socket api is necessary since socket is not standardized across platforms (WINSOCK, BSD Socket, Linux Socket…) at all. 

You need to elaborate a little more. “is not standardised across platforms at all”. In my eyes the reverse is true, the socket API *is* standardised by Posix and even Winsock2 is virtually identical to the Unix one (being just a Windows port of the BSD one).
Yes there are a lot of small differences and various extensions, but nothing fundamental unless you want to get really advanced.

Here is a very old socket imp which works on all three platforms:

  http://svn.opengroupware.org/SOPE/branches/sope-4.6/sope-core/NGStreams/NGSocket.m

and another one:

  https://github.com/opensource-apple/CF/blob/master/CFSocket.c


> Another reason is probably because of the sockaddr struct family. They have different sizes, different alignment(on different os),

Differences in size and alignment are completely handled by the clang C mapping and of no concern at all to the user of those structs?

> often need to cast the pointer around, and incredibly hard to use in pure swift manner.

Absolutely, the raw structs are hard to use as-is. But since you can extend C structs in Swift you can make them really nice. Look at this as an example:

  https://github.com/AlwaysRightInstitute/SwiftSockets/blob/master/Sources/SwiftSockets/SocketAddress.swift

it lets you do stuff like:

  let addr : sockaddr_in = “127.0.0.1:80”

or iterate through `addrinfo` since they are made conforming to the `Sequence` protocol, etc. And all that w/o actually wrapping the structs in yet another construct. Want a swiftier name for them? `typealias IPv4SocketAddress = sockaddr_in` does the trick ;-)


Note: I don’t want to push this as the ‘one’ solution the working group should use. But it actually is pretty similar to how other C-APIs (like CoreGraphics) are ‘Swifty'fied’. C based stuff doesn’t have to look bad in Swift, you can make that really nice.
Just saying (and providing demo code demonstrating the fact ;-))


> > A framework choosing a custom event loop certainly can work just fine today with the Posix functions available?
> I’m not quite sure what you mean here.

I meant that if you are working at such a low level that you are selecting your own runloop and scheduling mechanism (instead of using the builtin one), working with the Posix socket APIs should be no big deal.


> Sorry for my bad explanation, override is definitely not a good word choice. What I mean is 
> 
>     protocol Readable {
>         func read() -> Data?// how do we read
>    }
> 
>    protocol Writable {
>         func write(data: Data) // how do we write (send, sendfile, …) 
>    } 
> 
>    protocol Socket: Readable, Writable {}
> 
> so we can easily make something like:
> 
> class TLSSocket: Socket {
>     func read() -> Data? {
>     … ssl_read….
>     }
>     func write(data: Data) {
>     … ssl_write….
>     }    
> }
> 
> such that we can easily implement low level optimization and extent to different socket interfaces.

Yes, agreed. There should be protocols for such stuff. What is your opinion on my point:

> 3) Do you really want just a Socket, or is what you really want
>    a (byte) stream framework?

hh



More information about the swift-server-dev mailing list