#include "Winsock2.h"
1.MAKEWORD 宏 的使用
平臺:SDK 這個宏創(chuàng)建一個被指定變量連接而成的WORD變量。返回一個WORD變量。 (注:typedef unsigned short WORD;) WORD MAKEWORD( BYTE bLow, //指定新變量的低字節(jié)序; BYTE bHigh //指定新變量的高字節(jié)序; ); 例如: WORD wVersionRequested; wVersionRequested = MAKEWORD( 2, 2 ); #define MAKEWORD(a,b) ((WORD) (((BYTE) (a)) | ((WORD) ((BYTE) (b))) << 8)) makeword是將兩個byte型合并成一個word型,一個在高8位(b),一個在低8位(a) makelparam、makelong和makewparam都是一樣的,將兩個word型合并成一個dword型。一個在高16位,一個在低16位 delphi:word((byte(a)) or (word(byte(b))) shl 8); 比如a=2;b=1 2的二進制是00000010 1的二進制為00000001 B是表示高8位,A表示低8位 合并起來就是 100000010 想要的是MAKEWORE(1,1),MAKEWORD(2,2),有什么區(qū)別,是不是前面得只能一次接收一次,不能馬上發(fā)送,后面的能。 比如: #include <iostream.h> #include <windows.h> using namespace std; int main() { WORD wVersionRequested; wVersionRequested=MAKEWORD(2,2); cout << wVersionRequested << endl; return 0; } 輸出的結果是514,說明是將前面的2和后面的2組成一個新的WORD。即0000 0010 0000 0010 而這個結果正是:512 + 2 = 514.
2.
WSAStarup,是Windows SocKNDs Asynchronous的啟動命令、Windows下的網(wǎng)絡編程接口軟件 Winsock1 或 Winsock2 里面的一個命令。簡介
WSAStarup,即WSA(Windows SocKNDs Asynchronous,Windows套接字異步)的啟動命令。是Windows下的網(wǎng)絡編程接口軟件 Winsock1 或 Winsock2 里面的一個命令(Ps:Winsock 是由Unix下的BSD Socket發(fā)展而來,是一個與網(wǎng)絡協(xié)議無關的編程接口)。詳細說明
為了在應用程序當中調用任何一個Winsock API函數(shù),首先第一件事情就是必須通過WSAStartup函數(shù)完成對Winsock服務的初始化,因此需要調用WSAStartup函數(shù)。使用Socket的程序在使用Socket之前必須調用WSAStartup函數(shù)。該函數(shù)的第一個參數(shù)指明程序請求使用的Socket版本,其中高位字節(jié)指明副版本、低位字節(jié)指明主版本;操作系統(tǒng)利用第二個參數(shù)返回請求的Socket的版本信息。當一個應用程序調用WSAStartup函數(shù)時,操作系統(tǒng)根據(jù)請求的Socket版本來搜索相應的Socket庫,然后綁定找到的Socket庫到該應用程序中。以后應用程序就可以調用所請求的Socket庫中的其它Socket函數(shù)了。編輯本段函數(shù)原型
#include int PASCAL FAR WSAStartup ( WORD wVersionRequested, LPWSADATA lpWSAData );wVersionRequested Windows Sockets API提供的調用方可使用的最高版本號。高位字節(jié)指出副版本(修正)號,低位字節(jié)指明主版本號。lpWSAData 指向WSADATA數(shù)據(jù)結構的指針,用來接收Windows Sockets實現(xiàn)的細節(jié)。
3.返回本地主機的標準主機名。
//strHostIP 為 192.168.0.74 #include <Winsock2.h>
int PASCAL FAR gethostname(char FAR *name, int namelen);
name: 一個指向將要存放主機名的緩沖區(qū)指針。
namelen:緩沖區(qū)的長度。
注釋:
該函數(shù)把本地主機名存放入由name參數(shù)指定的緩沖區(qū)中。返回的主機名是一個以NULL結束的字符串。主機名的形式取決于Windows Sockets實現(xiàn)-它可能是一個簡單的主機名,或者是一個域名。然而,返回的名字必定可以在gethostbyname()和WSAAsyncGetHostByName()中使用。
返回值:
如果沒有錯誤發(fā)生,gethostname()返回0。否則它返回SOCKET_ERROR。應用程序可以通過WSAGetLastError()來得到一個特定的錯誤代碼。
錯誤代碼:
WSAEFAULT 名字長度參數(shù)太小。
WSANOTINTIALISED 在應用這個API前,必須成功地調用WSAStartup()。
WSAENTDOWN Windows Sockets實現(xiàn)檢測到了網(wǎng)絡子系統(tǒng)的錯誤。
WSAEINPROGRESS 一個阻塞的Windows Sockets操作正在進行。
4.gethostbyname()返回對應于給定主機名的包含主機名字和地址信息的hostent結構指針。結構的聲明與gethostaddr()中一致。
簡述
返回對應于給定主機名的主機信息。 #include <winsock2.h> struct hostent FAR *PASCAL FAR gethostbyname(const char FAR * name); name:指向主機名的指針。 Linux版 #include <netdb.h> struct hostent *gethostbyname(const char * hostname); 返回:非空指針——成功,空指針——出錯,同時設置h_errno gethostbyname()返回對應于給定主機名的包含主機名字和地址信息的hostent結構指針。結構的聲明與gethostaddr()中一致。 返回的指針指向一個由Windows Sockets實現(xiàn)分配的結構。應用程序不應該試圖修改這個結構或者釋放它的任何部分。此外,每一線程僅有一份這個結構的拷貝,所以應用程序應該在發(fā)出其他Windows Scokets API調用前,把自己所需的信息拷貝下來。 gethostbyname()實現(xiàn)沒有必要識別傳送給它的IP地址串。對于這樣的請求,應該把IP地址串當作一個未知主機名同樣處理。如果應用程序有IP地址串需要處理,它應該使用inet_addr()函數(shù)把地址串轉換為IP地址,然后調用gethostbyaddr()來得到hostent結構。 如果沒有錯誤發(fā)生,gethostbyname()返回如上所述的一個指向hostent結構的指針,否則,返回一個空指針。應用程序可以通過WSAGetLastError()來得到一個特定的錯誤代碼。
5. inet_ntoa
函數(shù)功能:將
網(wǎng)絡地址轉換成“.”點隔的字符串格式。
所需庫: winsock.h
也可以使用:
頭文件 | Winsock2.h |
lib | Ws2_32.lib |
dll | Ws2_32.dll |
即在程序開頭寫:
#include <WINSOCK2.h>
#pragma comment(lib,"WS2_32.LIB")
函數(shù)原型: char FAR* PASCAL FAR inet_ntoa( struct
in_addr in);
MSDN上本函數(shù)的原型描述為:unsigned long inet_addr( __in const char *cp);
in:一個表示Internet主機地址的結構。
注釋: 本函數(shù)將一個用in參數(shù)所表示的Internet地址結構轉換成以“.” 間隔的諸如“a.b.c.d”的字符串形式。請注意inet_ntoa()返回的字符串存放在WINDOWS套接口實現(xiàn)所分配的內存中。
應用程序不應假設該內存是如何分配的。在同一個線程的下一個WINDOWS套接口調用前,數(shù)據(jù)將保證是有效。
返回值: 若無錯誤發(fā)生,inet_ntoa()返回一個字符指針。否則的話,返回NULL。其中的數(shù)據(jù)應在下一個WINDOWS套接口調用前復制出來。
相關函數(shù):inet_addr().
6.hostent 是host entry的縮寫,該結構記錄主機的信息,包括主機名、別名、地址類型、地址長度和地址列表。之所以主機的地址是一個列表的形式,原因是當一個主機有多個網(wǎng)絡接口時,自然有多個地址。hostent的定義如下:
struct hostent *gethostbyname(const char *name);
這個函數(shù)的傳入值是域名或者主機名,例如"www.google.cn"等等。傳出值,是一個hostent的結構。如果函數(shù)調用失敗,將返回NULL。
struct hostent
{
char *h_name;
char **h_aliases;
int h_addrtype;
int h_length;
char **h_addr_list;
#define h_addr h_addr_list[0]
};
hostent->h_name
表示的是主機的規(guī)范名。例如www.google.com的規(guī)范名其實是www.l.google.com。
hostent->h_aliases
表示的是主機的別名.www.google.com就是google他自己的別名。有的時候,有的主機可能有好幾個別名,這些,其實都是為了易于用戶記憶而為自己的網(wǎng)站多取的名字。
hostent->h_addrtype
表示的是主機ip地址的類型,到底是ipv4(AF_INET),還是pv6(AF_INET6)
hostent->h_length
表示的是主機ip地址的長度
hostent->h_addr_lisst
表示的是主機的ip地址,注意,這個是以網(wǎng)絡字節(jié)序存儲的。千萬不要直接用printf帶%s參數(shù)來打這個東西,會有問題的哇。所以到真正需要打印出這個IP的話,需要調用inet_ntop()。
const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) :
這個函數(shù),是將類型為af的網(wǎng)絡地址結構src,轉換成主機序的字符串形式,存放在長度為cnt的字符串中。返回指向dst的一個指針。如果函數(shù)調用錯誤,返回值是NULL。
HRESULT GetHostInfo(CString& strHostIP)
{
int nCheck = 0;
WORD wVersion = 0;
CString strName = _T("");
CString strIP = _T("");
in_addr *pIPAddr = NULL;
HOSTENT *pstHostInfo = NULL;
char chrName[256];
WSADATA wsaData;
wVersion = MAKEWORD(2, 2);
nCheck = WSAStartup(wVersion, &wsaData);
nCheck |= gethostname(chrName, 256); if(nCheck != 0) { return E_FAIL; } strName = (CString)chrName; #ifdef _UNICODE USES_CONVERSION; pstHostInfo = gethostbyname(W2A(strName)); #else pstHostInfo = gethostbyname(strName.GetBuffer(strName.GetLength())); #endif if(pstHostInfo != NULL) { LPBYTE pBuffer = NULL; pBuffer = new BYTE[4]; memcpy(pBuffer, pstHostInfo->h_addr_list[0], 4); pIPAddr = (in_addr*)pBuffer; strIP = inet_ntoa(*pIPAddr); delete [] pBuffer; pBuffer = NULL; } else return E_FAIL; strHostIP = strIP; return S_OK;
}