)头文件

windows下winsock.h或winsock2.h

linux下netinet/in.h(大部分都在这儿),unistd.h(close函数在这儿),sys/socket.h(在in.h里已经包含了,可以省了)

2)初始化

windows下需要用WSAStartup启动Ws2_32.lib,并且要用#pragma comment(lib,"Ws2_32")来告知编译器链接该lib。

linux下不需要

3)关闭socket

windows下closesocket(...)

linux下close(...)

4)类型

windows下SOCKET

linux下int(我喜欢用long,这样保证是4byte,因为-1我总喜欢写成0xFFFF)

5)获取错误码

windows下getlasterror()/WSAGetLastError()

linux下,未能成功执行的socket操作会返回-1;如果包含了errno.h,就会设置errno变量

6)设置非阻塞

windows下ioctlsocket()

linux下fcntl(),需要头文件fcntl.h

7)send函数最后一个参数

windows下一般设置为0

linux下最好设置为MSG_NOSIGNAL,如果不设置,在发送出错后有可能会导致程序退出

8)毫秒级时间获取

windows下GetTickCount()

linux下gettimeofday()

9)多线程

windows下包含process.h,使用_beginthread和_endthread

linux下包含pthread.h,使用pthread_create和pthread_exit

10)用IP定义一个地址(sockaddr_in的结构的区别)

windows下addr_var.sin_addr.S_un.S_addr

linux下addr_var.sin_addr.s_addr

而且Winsock里最后那个32bit的S_addr也有几个以联合(Union)的形式与它共享内存空间的成员变量(便于以其他方式赋值),而Linux的Socket没有这个联合,就是一个32bit的s_addr。遇到那种得到了是4个char的IP的形式(比如127一个,0一个,0一个和1一个共四个char),WinSock可以直接用4个S_b来赋值到S_addr里,而在Linux下,可以用边向左移位(一下8bit,共四下)边相加的方法赋值。

11)异常处理

linux下当连接断开,还发数据的时候,不仅send()的返回值会有反映,而且还会像系统发送一个异常消息,如果不作处理,系统会出BrokePipe,程序会退出。为此,send()函数的最后一个参数可以设MSG_NOSIGNAL,禁止send()函数向系统发送异常消息。

套接字(socket)当今已成为最流行的网络通信应用程序接口。套接字最初是由加利福尼亚大Berkeley分校为Unix操作系统开发的网络通信接口,后来它又被移植到DOS与Windows系统,特别是近几年来互联网络在全世界范围内被广泛普及并且增长迅猛,进一步奠定了它在网络通信程序开发领域的主宰地位。跨系统网络互联的呼声在我国也越来越高。近来,在开发的银行与证券联网系统中,我们尝试做

了由Unix Sockets到Windows Sockets通信应用程序的移植,有所体会,望能将移植过程中应该注意的几点问题与热心于这方面工作的人们共同作以探讨,以期能起到抛砖引玉的作用。



1、修改头文件的定义

在Unix Sockets应用程序中包含头文件的语句为#include,而在Windows Sockets应用程序中相应语句应为 #include。Windows Sockets的实现由两部分组成,即开发组件与运行组件。开发组件是供程序

员开发Windows Sockets 应用程序使用的,它包括Windows Sockets应用程序接口函数库、头文件以及一些介绍Windows Sockets实现的文档,其中头文件winsock.h中包含了Windows Sockets 实现所定义的宏、常数值、数据结构和函数调用接口原型。Winsock.h是编写Windows Sockets应用程序必须包含的头文件。



2、Windows Sockets DLL初始化与资源释放

在Windows Sockets的接口函数中,提供了WSAStartup()与WSACleanup()两个函数,用于在程序开始时初始化Windows Sockets DLL和程序结束时释放Windows Sockets DLL资源,它们是编写Windows Sockets应用程序时必须使用的两个函数。



3、将套接字的类型由int改为SOCKET

在Unix系统中,套接字类型定义为int型,而在Windows系统中,套接字类型被定义为SOCKET型,即unsigned int型。



4、错误码的获取与设置

在Unix系统中,获取、设置错误码使用全局变量errno,而在Windows系统中则应将其改为用函数WSAGetLastError()和WSASetLastError()。Windows Sockets 为了与多线程环境兼容,提供了两个出错处理函数WSAGetLastError()与WSASetLastError()来获取与设置当前线程的最近错误号,而不再使用Unix系统中的全局变量errno和h_errno。



5、关闭套接字

在Unix系统中使用close()函数来关闭套接字,而在Windows系统中则用closesocket()函数。



6、对套接字的控制

在Unix系统中,使用ioctl()函数和fcntl()函数实现对套接字的控制,而在Windows系

统中则应使用ioctlsocket()函数。



7、getsockopt()和setsockopt()函数的处理

在Unix Sockets和Windows Sockets中对这两个函数提供的支持不同。在Windows Sockets中getsockopt()与setsockopt()不支持的Berkeley Sockets选项有:



SO_RCVLOWAT 接受低潮标志



SO_RCVTIMEO 接受超时



SO_SNDLOWAT 发送低潮标志



SO_SNDTIMEO 发送超时



IP_OPTIONS 取得IP头中的选项



TCP_MAXSEG 取得TCP最大尺寸



SO_ACCEPTCONN 套接字正在监听



SO_ERROR 取错误状态并清除



SO_TYPE 套接字类型



使用不支持的选项将返回错误码WSAENOPROTOOPT,它由WSAGetLastError()函数返回。由于提供的支持不同,进行移植时若有必要应修改相应的源程序。



8、使用宏FD_XXX来控制fd_set结构

由于Windows Sockets 某些函数在接口上虽然与Unix Sockets一致,但是它们的内部实现却不一样,例如,在函数select()的参数中,Unix Sockets实现套接字集合使用的是位掩码,但在Windows Sockets中却是使用一个SOCKET的数组。虽然套接字的集合仍由fd_set类型表示,但在Unix Sockets 源文件中直接修改fd_set结构的代码在Windows Sockets环境下将不能正常工作。因此,在进行移植时应将源程序中对结构fd_set的直接修改改为通过使用FD_XXX宏来修改。



9、应在Windows Sockets程序中尽量使用WSA宏

在Windows Sockets的头文件中定义了许多以WSA开头的宏,在程序中使用这些宏,

可以大大地增加程序的可读性。例如:



errno = WSAGetLastError();



if (errno = WSAEWOULDBLOCK) {



……



}



这些宏是Windows Sockets就应用程序实现过程中可能会出现的错误,为便于

程序的读写而专门做出的扩充,它是Windows Sockets应用程序编写人员开发

程序时共同遵循的规范,因此应尽量使用这些宏,以增加程序的可读性。



10、阻塞调用的处理

Windows是非抢先多任务环境,各任务之间的切换是通过消息驱动的,如果一

个应用程序不能主动放弃其控制权,别的应用程序就不能够执行,这一点与

Unix操作系统有着本质的区别。对于从Unix Sockets环境中移植来的应用程序

来说,阻塞问题必须考虑。



为解决阻塞问题,Windows Sockets特增设了如下几个阻塞处理函数:



WSAIsBlocking() 检测阻塞调用是否正在进行



WSACancelBlockingCall() 取消一个正在进行的阻塞调用



WSASetBlocking() 设置自己的阻塞处理例程



WSAUnhookBlockingHook() 恢复默认的阻塞处理例程



为不影响原来环境中的阻塞处理例程,在安装自己的阻塞处理例程时,应注意保存返回的先前安装的阻塞处理例程的程序实例指针,并在处理结束后恢复。



11、尽量将阻塞调用改为基于消息的异步操作

在Windows Sockets网络程序设计中,尽管它允许阻塞操作,但是一个阻塞可能阻塞整个Windows环境,而在Unix Sockets程序中,套接字的默认操作模式却是阻塞的。Windows Sockets为了支持Windows消息驱动机制,对网络事件采用了基于消息的异步存取策略,较好的解决了阻塞问题。为此,建议最好将源程序中的阻塞调用改为基于消息的异步操作。



Windows Sockets为实现异步存取操作增设了如下的有关函数:



WSAAsyncSelect() 标准Berkeley函数select()的异步版本



WSAAsyncGetXByY() 标准Berkeley函数getXbyY()的异步版本



WSACancelAsyncRequest() 取消函数WSAAsyncGetXByY()执行中的实例



由Unix Sockets应用程序向Windows Sockets的移植是一件比较繁琐的工作,在移植中除了以上Sockets具体实现直接相关的几点外,还应注意程序开发环境的的差异,这时程序上也应作一些相应的调整,例如,在Windows应用程序中有关的一些指针都应设为FAR类型等,这里就不再一一赘述

Socket程序从windows移植到linux下需要注意的的更多相关文章

  1. C/C++ Windows移植到Linux

    近期写了有关Socket的程序,需要从windows移植到linux.现把有用的东东收集整理记录下来. 1.头文件windows下winsock.h或winsock2.h:linux下netinet/ ...

  2. 几款抓包工具在windows,mac,linux下的支持分析

    抓包工具的使用 几款抓包工具在windows,mac,linux下的支持分析 抓包工具简介 Chrome/Firefox 开发者工具: 浏览器内置,方便易用 Fiddler/Charles: 基于代理 ...

  3. 简单API练手:(1)复制自身程序到windows目录和系统目录下;(2)获得系统的相关信息。

    1.复制自身程序到windows目录和系统目录下: #include <windows.h> #include <stdio.h> #include <string.h& ...

  4. 移植ARM linux下远程连接工具dropbear

    移植ARM linux下远程连接工具dropbear 原文地址:http://www.cnblogs.com/NickQ/p/9010529.html 移植zlib 下载地址:https://gith ...

  5. windows客户端远程访问linux下mysql方法

    windows客户端远程访问linux下mysql方法 1. 改表法.可能是你的帐号不允许从远程登陆,只能在localhost.这个时候只要在localhost的那台电脑,登入mysql后,更改 &q ...

  6. windows下系统移植到linux下出现的问题

    今天遇到了一个之前没有遇到的问题,记录一下. 我们是在windows下进行开发的,最终系统是部署在linux服务器上. 在windows一切正常,但是部署到linux下时,有些功能不能用了.通过log ...

  7. 我将系统从Windows迁移至Linux下的点点滴滴

    一.写在最前 由于本人的技术水平有限,难免会出现错误.本文对任何一个人有帮助都是我莫大的荣幸,任何一个大神对我的点拨,我都会感激不尽. 二.技术选型 在2013年8月低的时候,公司中了XXX市场监督局 ...

  8. window应用移植到Linux下(应用移植)

     配置QT的环境变量,这台电脑à属性à高级系统设置à高级à环境变量à系统变量àpathàC:\Qt\Qt5.3.0\5.3\mingw482_32\bin;C:\Qt\Qt5.3.0\Tools\ ...

  9. 吐血记录微信小程序授权获取Unionid及linux下使用bouncycastle解密用户数据 遇到的坑

    背景 公司小程序上线了,发现系统无法拿到一些用户的UniondID.但是上线前的测试一切都是正常的. 坑1 经排查,发现一些用户通过下面的接口无法得到unionid https://api.weixi ...

随机推荐

  1. Redis总结(七)Redis运维常用命令

    redis 服务器端命令 redis 127.0.0.1:6380> time  ,显示服务器时间 , 时间戳(秒), 微秒数 1) "1375270361" 2) &quo ...

  2. [SDOI2015]约数个数和

    Sol 首先有个结论 \(\sum_{i=1}^{m}\sum_{j=1}^{n}d(i*j)=\sum_{i=1}^{m}\sum_{j=1}^{n}\sum_{x|i}\sum_{y|i}[gcd ...

  3. [BZOJ1610] [Usaco2008 Feb] Line连线游戏 (set)

    Description Farmer John最近发明了一个游戏,来考验自命不凡的贝茜.游戏开始的时 候,FJ会给贝茜一块画着N (2 <= N <= 200)个不重合的点的木板,其中第i ...

  4. java设计模式-----11、代理模式

    Proxy模式又叫做代理模式,是构造型的设计模式之一,它可以为其他对象提供一种代理(Proxy)以控制对这个对象的访问. 所谓代理,是指具有与代理元(被代理的对象)具有相同的接口的类,客户端必须通过代 ...

  5. 身份证号码的正则表达式及验证详解(JavaScript,Regex)

    简言 在做用户实名验证时,常会用到身份证号码的正则表达式及校验方案.本文列举了两种验证方案,大家可以根据自己的项目实际情况,选择适合的方案. 身份证号码说明 居民身份证号码,正确.正式的称谓应该是&q ...

  6. Django 2.0 学习(04):Django数据库

    数据库设置/配置 打开mysite/settings.py,我们会发现Django是用的是默认的数据库SQLite,如下图所示: Django也是支持其它数据库的,比如PostgreSQL.MySQL ...

  7. 设计模式——桥接模式(C++实现)

    [root@ ~/learn_code/design_pattern/18_bridge]$ cat Abstraction.h #ifndef _ABSTRACTION_H_ #define _AB ...

  8. C++调用C方法

    //1,编译静态库 libtest.a gcc -c test.c -o test.o ar rc libtest.a test.o //2,编译main函数 g++ -o main main.cpp ...

  9. AvalonJS前端开发源码

    avBody = avalon.define("avBody", function (vm) { vm.Address = "";//地址 vm.BrandMo ...

  10. java ———基础总结

    计算机语言的分类:  机器语言: 是计算机唯一能接受和执行的语言,只有二进制数字表示. 汇编语言: 是用助记符表示指令功能的计算机语言. 高级语言: 与自然语言相近并为计算机所接受和执行的计算机语言. ...