简体   繁体   English

Winsock 2便携性

[英]Winsock 2 portability

I'm about to develop some sockets related stuff in C++ and would like the software to be as portable between Windows and Linux as possible right from the start (making it portable later is tricky.) 我即将在C ++中开发一些与套接字相关的东西,并且希望软件从一开始就尽可能在Windows和Linux之间移植(以后便携它很棘手。)

I've looked at different libraries, there is one for C++ from alhem.net and of course there is boost::asio. 我看过不同的库,有一个来自alhem.net的 C ++,当然还有boost :: asio。 boost::asio looks very promising but would be a very big dependency for applications this small. boost :: asio看起来非常有前景,但对于这么小的应用程序来说是一个非常大的依赖。

Is it even worth writing the stuff myself or should I just use a library? 是否值得自己写这些东西或者我应该只使用图书馆? If I do it myself what would be the main pitfalls? 如果我自己做,那么主要的陷阱是什么?

I've developed a few portable wrappers around sockets. 我在套接字周围开发了一些便携式包装器。 Make sure you don't go down the crappy lane of no return that is constituted of WinSock2 events. 确保你没有沿着由WinSock2事件构成的无法回归的蹩脚线路走下去。 Other than that, as I see it, the biggest differences are: 除此之外,正如我所看到的,最大的区别是:

  • to start networking in Windows, you need to call ::WSAStartup() , to shut it down in Windows, run ::WSACleanup() ; 要在Windows中启动网络,你需要调用::WSAStartup() ,在Windows中关闭它,运行::WSACleanup() ; in Linux do nothing, 在Linux中什么都不做,
  • close() in Linux is closesocket() in Windows, Linux中的close()是在Windows中的closesocket()
  • default buffer sizes differ between both drivers and operating systems, so make sure to set them using SO_RCVBUF and SO_SNDBUF , 默认缓冲区大小在驱动程序和操作系统之间有所不同,因此请确保使用SO_RCVBUFSO_SNDBUF进行设置,
  • SO_REUSEADDR steals the address on Windows, allows frequent re-opening on Linux; SO_REUSEADDR窃取Windows上的地址,允许在Linux上频繁重新打开; you'd probably only want to use this flag in Linux, 你可能只想在Linux中使用这个标志,
  • making a socket non-blocking uses ::ioctlsocket() in Windows, ::fcntl() in Linux, 使用套接字非阻塞在Windows中使用::ioctlsocket() ,在Linux中使用::fcntl()
  • the header files are different, <sys/socket.h> and friends in Linux, <WinSock.h> in Windows, 头文件不同, <sys/socket.h>和Linux中的朋友,Windows中的<WinSock.h>
  • to go portable, the easiest way is probably to use ::select() to wait for data to arrive, 要便携,最简单的方法可能是使用::select()等待数据到达,
  • fd_set s are totally different on Windows/Linux; fd_set在Windows / Linux上完全不同; this is only relevant if you need to optimize initialization of fd_set s, such as when adding/removing arbitrary sockets, 这只有在你需要优化fd_set的初始化时才有意义,例如在添加/删除任意套接字时,
  • in Windows, any thread hanging on the socket is released with an error code when the socket is closed, in Linux the thread remains waiting. 在Windows中,当套接字关闭时,任何挂在套接字上的线程都会发布错误代码,在Linux中线程仍在等待。 If the thread is blocking the socket with for instance ::recvfrom() , you might consider using ::sendto() to release the stalling thread under Linux. 如果线程使用例如::recvfrom()阻塞套接字,您可以考虑使用::sendto()来释放Linux下的停滞线程。

Everything else I ever needed just worked out of the låda. 我所需要的其他所有东西都是出自låda。

Winsocks aren't very compatible with Posix sockets: Winsocks与Posix插座不太兼容:

  • In Winsocks a socket is of type SOCKET . 在Winsocks中,套接字的类型为SOCKET On Posix it's simply a file descriptor ( int ), on which you can perform normal read() and write() calls. 在Posix上,它只是一个文件描述符( int ),您可以在其上执行正常的read()write()调用。
  • They don't return errors the same way. 它们不会以同样的方式返回错误。
  • They don't support some options on recv() and send() . 它们不支持recv()send()一些选项。
  • You have to initialize and unitialize the Winsocks library with two specials functions. 您必须使用两个特殊功能初始化和组合Winsocks库。
  • I don't think you can close Windows sockets with shutdown() or close() . 我不认为你可以用shutdown()close()关闭Windows套接字。 It's something like closesocket() instead. 它就像closesocket()

There must be more differences, but that's what I can remember right now. 必须有更多的差异,但这是我现在能记住的。 If you want portability with Winsocks, you'll have a small library for closing a socket, printing an error message and so on. 如果您希望使用Winsocks进行移植,那么您将拥有一个用于关闭套接字,打印错误消息等的小型库。

I'd probably go with boost::asio , personnally (I've never used it, though). 我可能会和boost::asio一起去个人(我从来没有用过它)。

Take a look at the "Adaptive Communications Environment" (ACE) library: (ACE Home Page) It provides some nice abstractions and a lot of flexibility all rolled up in a portable library that supports Windows, MacOS and Linux. 看看“自适应通信环境”(ACE)库: (ACE主页)它提供了一些很好的抽象和很多灵活性,所有这些都集成在支持Windows,MacOS和Linux的可移植库中。 It has a bit of a steep learning curve, but I got very good value from it. 它有一个陡峭的学习曲线,但我从中获得了非常好的价值。

Honestly, I'd use boost::asio as a first preference. 老实说,我会使用boost :: asio作为首选。 If you really want to get down and dirty with the sockets API, you can use the standard BSD-style sockets API on both Windows and Linux - it's just that on Windows you'll have to link to (and initialize) Winsock2, whereas on Linux you won't have a separate library to link against. 如果你真的想要了解套接字API,你可以在Windows和Linux上使用标准的BSD风格的套接字API - 只是在Windows上你必须链接到(并初始化)Winsock2,而在Linux你不会有一个单独的库来链接。

How much socket stuff will you be using? 你将使用多少套接字? I've done several apps where the socket stuff was pretty high level (open, read, write), and worked perfectly from Windows to Linux. 我已经完成了几个应用程序,其中套接字的东西非常高(开放,读取,写入),并且从Windows到Linux完美地工作。 If it's more than that - go with boost. 如果它不止于此 - 请加强。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM