2019獨角獸企業重金招聘Python工程師標準>>>
1、一些常用函數的移植?
http://www.vckbase.com/document/viewdoc/?id=1586
2、網絡?
socket相關程序從Windows移植到Linux下需要注意的:
1)頭文件?
Windows下winsock.h/winsock2.h?
Linux下sys/socket.h?
錯誤處理:errno.h
2)初始化?
Windows下需要用WSAStartup?
Linux下不需要
3)關閉socket?
Windows下closesocket(...)?
Linux下close(...)
4)類型?
Windows下SOCKET?
Linux下int?
如我用到的一些宏:?
#ifdef WIN32?typedef int socklen_t;?typedef int ssize_t;?
#endif#ifdef __Linux__?typedef int SOCKET;?typedef unsigned char BYTE;?typedef unsigned long DWORD;?
#define FALSE 0?
#define SOCKET_ERROR (-1)?#endif
5)綁定地址的結構體
名稱相同,都是struct sockaddr、struct sockaddr_in,這兩者通常轉換使用;
在Windows下面名稱都是大寫,而在Linux下為小寫
常用:
Linux下:
sockaddr_in destAddr;destAdd.sin_family=AF_INET;
destAddr.sin_port=htons(2030);
destAddr.sin_addr.s_addr=inet_addr("192.168.1.1");
Windows下:
SOCKADDR_IN destAddr;
destAddr.sin_addr.S_un.S_addr=inet_addr("192.168.1.1");
但結構體中成員的名稱不同
Windows中結構體成員
struct sockaddr_in {short sin_family;u_short sin_port;struct in_addr sin_addr;char sin_zero[8]; };
struct sockaddr {u_short sa_family;char sa_data[14]; };
struct in_addr {union {struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;struct { u_short s_w1,s_w2; } S_un_w;u_long S_addr;} S_un; };
下面的一些宏可以使windows下的程序移植到linux下(通過類型的重新定義,使代碼具有linux和windows下的移植性)
?
5)獲取錯誤碼?
Windows下getlasterror()/WSAGetLastError()?
Linux下errno變量
6)設置非阻塞?
Windows下ioctlsocket()?
Linux下fcntl() <fcntl.h>
7)send函數最后一個參數?
Windows下一般設置為0?
Linux下最好設置為MSG_NOSIGNAL,如果不設置,在發送出錯后有可 能會導致程序退出。
8)send函數最后一個參數?
windows下一般設置為0?
linux下最好設置為MSG_NOSIGNAL,如果不設置,在發送出錯后有可 能會導致程序退出。?
?
9)毫秒級時間獲取?
Windows下GetTickCount()?
Linux下gettimeofday()
10)數據類型的一些轉化
通用的:
小端到大端(網絡協議使用)的轉換:htonl, htons?
點分十進制IP和整數之間的相互轉換:inet_addr()(該函數將點分十進制轉為整數),inet_aton(),inet_ntoa(),inet_pton()(linux下獨有? 該函數可以實現相互之間的轉換)
使用到的頭文件不相同,linux下用man命令查詢。
另外注意:
linux下使用的套接字為伯克利套接字,因此在select()函數的使用上(第一個參數的設置)也有區別;
windows下為了與伯克利套接字匹配,第一個參數是無所謂,一般可設為0;
int maxfdp是一個整數值,是指集合中所有文件描述符的范圍,即所有文件描述符的最大值加1,不能錯!
?
?
3、多線程?
?
多線程: (win)process.h --〉(Linux)pthread.h?
_beginthread --> pthread_create?
_endthread --> pthread_exit
?
一、linux下的socket編程:
1、客戶端執行步驟依次如下:
socket()
connect()
send()或者recv()
close()
注意的是,connect之前要填充地址結構體,IP地址轉換為網絡字節序,一般用inet_aton().
2、服務器端:
socket()
bind()
listen()
accpet()
recv()或者send()
close()
(ps:一般通過將send()和recv()的最后一個參數賦為0或者1來區分阻塞與非阻塞,其中0對應阻塞,1對應非阻塞)
二、windows下的網絡編程:
做過windows網絡編程的人都知道,微軟的MFC把復雜的WinSock API函數封裝到類里,這使得編寫網絡應用程序更容易。即windows既提供上層的網絡API函數也提供底層的API函數。
1、對于采用上層的API函數而言:若采用csocket類定義一個對象obj的話,那么進行網絡編程的步驟如下:
客戶端:
obj.Create()
obj.Connect()
obj.Receive()或者obj.Send()
obj.Close()
服務器端:
先調用AfxSocketInit()檢測協議棧安裝情況
obj.Create()
obj.Listen()
obj.Accpet()
obj.Receive()或者obj.Send()
obj.Close()
2、對于采用底層的API函數而言,步驟如下:
客戶端:
WSAStartup()
socket()
connect()
send()或者recv()
closesocket()
服務器端:
WSAStartup()
socket()
bind()
listen()
accpet()
send()
recv()
closesocket()
(ps:windows下CSocket類為同步方式,有阻塞現象;CASyncSocket為異步方式,無阻塞現象。)
通過以上比較可以發現:linux下的網絡編程與windows下采用底層的API類似,但是也有區別:
區別一:windows下需加上WSAStartup()函數
區別二:關閉socket:linux為close(),windows為closesocket()
windows下采用上層的API,一般有CSocket和CAsynSocket這兩種類型的類
這種情況以下socket函數一般的首字母大寫。而底層的API不管是windows下的還是linux下的socket函數首字母都是小寫的。
?
socket編程在windows和linux下的區別