Linux,OSX和Windows上的基本TCP客户端

时间:2013-12-31 06:08:54

标签: c linux windows macos tcp

我想在C中创建一个适用于Windows,Linux和osx(最重要)的TCP客户端。我在SO上找到的代码可能适用于Linux但不适用于osx,反之亦然。那么我需要确保它适用于所有三个?

谢谢!

1 个答案:

答案 0 :(得分:2)

假设您计划编写代码以使用BSD套接字API,您会发现大多数适用于Linux的TCP客户端代码都可以在MacOS / X上运行,几乎不需要修改,反之亦然。

让代码在Windows下工作也有点棘手,因为所需的#includes是不同的,并且在很多情况下,Windows的TCP堆栈(又名WinSock)的行为与TCP的行为略有不同其他两个操作系统的堆栈。也就是说,Windows确实支持大多数BSD套接字API,并且通过一些#ifdef-ing,你可以提出一个程序,它将在所有三个操作系统上正确编译和运行。当然,您需要对所有三个操作系统进行测试和调试;从来没有假设只是因为某个操作系统上的某些东西可以在任何地方运行。

根据您的计划的特定需求(以及您的兴趣),遵循Duck的建议并找到已经为您完成上述工作的网络库可能是有意义的;但如果你喜欢“自己动手”,那也是可行的。写入BSD套接字API时的一个好方法是:每当您发现一段代码必须针对不同的操作系统进行不同的编写时,将该代码段的实现隐藏在一个函数中(使用#ifdef以便正确的代码在每个操作系统下编译),这样你的程序的其余部分就不必记住如何处理那些令人不快的细节了。做足够多次,你将最终成为自己的跨平台网络库的自豪维护者;)

我建议您首先在Linux和/或OS / X下运行您的程序,一旦您对它感到满意,然后将其移植到Windows。将网络代码移植到Windows时要注意的一些“问题”:

  1. 在Windows下,您可以#include windows.h或winsock2.h来获取所需的网络定义。 (如果你想要更新的WinSock2 API,你必须包含winsock2.h,并且总是在任何#include的windows.h之前做,否则你将得到错误的API版本......这是一个真正的马戏团)

  2. 在Windows下,您必须在执行任何网络工作之前调用WSAStartup()(如果您忘记了,所有网络调用都会出错)

  3. 在MacOS / X和Linux下,文件描述符和套接字在很大程度上是可以互换的(即你可以在STDIN_FILENO等上选择())。在Windows下,它们不是。

  4. 在MacOS / X和Linux下,您可以通过检查errno找出呼叫失败的原因。在Windows下,您可以调用WSAGetLastError()。

  5. 在MacOS / X和Linux下,使用close()销毁套接字。在Windows下,您可以使用closesocket()。

  6. 在MacOS / X和Linux下,您可以(如果选择)在TCP套接字上调用read()和write()来分别接收/发送数据。在Windows下,这将无效,您必须仅调用send()和recv()。 (send()和recv()也可以在MacOS / X和Linux下工作)

  7. 要在Windows下将套接字设置为非阻塞模式,您必须调用ioctlsocket(fd,FIONBIO和& mode)。在MacOS / X和Linux下,你调用fcntl(fd,F_SETFL,flags)。

  8. 更有趣的Windows网络问题可以在WinSock Lame List阅读。