)頭文件
windows下winsock.h或winsock2.h
linux下netinet/in.h(大部分都在這兒),unistd.h(close函數在這兒),sys/socket.h(在in.h裏已經包含了,能夠省了)linux
2)初始化
windows下須要用WSAStartup啓動Ws2_32.lib,而且要用#pragma comment(lib,"Ws2_32")來告知編譯器連接該lib。
linux下不須要windows
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()socket
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通訊應用程序的移植,有所體會,望能將移植過程當中應該注意的幾點問題與熱心於這方面工做的人們共同做以探討,以期能起到拋磚引玉的做用。 一、修改頭文件的定義 在Unix Sockets應用程序中包含頭文件的語句爲#include,而在Windows Sockets應用程序中相應語句應爲 #include。Windows Sockets的實現由兩部分組成,即開發組件與運行組件。開發組件是供程序 員開發Windows Sockets 應用程序使用的,它包括Windows Sockets應用程序接口函數庫、頭文件以及一些介紹Windows Sockets實現的文檔,其中頭文件winsock.h中包含了Windows Sockets 實現所定義的宏、常數值、數據結構和函數調用接口原型。Winsock.h是編寫Windows Sockets應用程序必須包含的頭文件。 二、Windows Sockets DLL初始化與資源釋放 在Windows Sockets的接口函數中,提供了WSAStartup()與WSACleanup()兩個函數,用於在程序開始時初始化Windows Sockets DLL和程序結束時釋放Windows Sockets DLL資源,它們是編寫Windows Sockets應用程序時必須使用的兩個函數。 三、將套接字的類型由int改成SOCKET 在Unix系統中,套接字類型定義爲int型,而在Windows系統中,套接字類型被定義爲SOCKET型,即unsigned int型。 四、錯誤碼的獲取與設置 在Unix系統中,獲取、設置錯誤碼使用全局變量errno,而在Windows系統中則應將其改成用函數WSAGetLastError()和WSASetLastError()。Windows Sockets 爲了與多線程環境兼容,提供了兩個出錯處理函數WSAGetLastError()與WSASetLastError()來獲取與設置當前線程的最近錯誤號,而再也不使用Unix系統中的全局變量errno和h_errno。 五、關閉套接字 在Unix系統中使用close()函數來關閉套接字,而在Windows系統中則用closesocket()函數。 六、對套接字的控制 在Unix系統中,使用ioctl()函數和fcntl()函數實現對套接字的控制,而在Windows系 統中則應使用ioctlsocket()函數。 七、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()函數返回。因爲提供的支持不一樣,進行移植時如有必要應修改相應的源程序。 八、使用宏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宏來修改。 九、應在Windows Sockets程序中儘可能使用WSA宏 在Windows Sockets的頭文件中定義了許多以WSA開頭的宏,在程序中使用這些宏, 能夠大大地增長程序的可讀性。例如: errno = WSAGetLastError(); if (errno = WSAEWOULDBLOCK) { …… } 這些宏是Windows Sockets就應用程序實現過程當中可能會出現的錯誤,爲便於 程序的讀寫而專門作出的擴充,它是Windows Sockets應用程序編寫人員開發 程序時共同遵循的規範,所以應儘可能使用這些宏,以增長程序的可讀性。 十、阻塞調用的處理 Windows是非搶先多任務環境,各任務之間的切換是經過消息驅動的,若是一 個應用程序不能主動放棄其控制權,別的應用程序就不可以執行,這一點與 Unix操做系統有着本質的區別。對於從Unix Sockets環境中移植來的應用程序 來講,阻塞問題必須考慮。 爲解決阻塞問題,Windows Sockets特增設了以下幾個阻塞處理函數: WSAIsBlocking() 檢測阻塞調用是否正在進行 WSACancelBlockingCall() 取消一個正在進行的阻塞調用 WSASetBlocking() 設置本身的阻塞處理例程 WSAUnhookBlockingHook() 恢復默認的阻塞處理例程 爲不影響原來環境中的阻塞處理例程,在安裝本身的阻塞處理例程時,應注意保存返回的先前安裝的阻塞處理例程的程序實例指針,並在處理結束後恢復。 十一、儘可能將阻塞調用改成基於消息的異步操做 在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類型等,這裏就再也不一一贅述