當(dāng)前位置:首頁(yè) > EDA > 電子設(shè)計(jì)自動(dòng)化
[導(dǎo)讀]IPv4 最初是由美國(guó)國(guó)防部開(kāi)發(fā)的用于網(wǎng)際互聯(lián)(IP)協(xié)議,后來(lái)它不僅發(fā)展了TCP,而且還進(jìn)一步發(fā)展了IPv4(IP 協(xié)議4.0版)。IPv4現(xiàn)在已經(jīng)廣泛應(yīng)用于Internet網(wǎng)絡(luò)中,同時(shí)也應(yīng)用于大多數(shù)計(jì)算機(jī)系統(tǒng),局域網(wǎng)和廣域網(wǎng)中。然而

IPv4 最初是由美國(guó)國(guó)防部開(kāi)發(fā)的用于網(wǎng)際互聯(lián)(IP)協(xié)議,后來(lái)它不僅發(fā)展了TCP,而且還進(jìn)一步發(fā)展了IPv4(IP 協(xié)議4.0版)。IPv4現(xiàn)在已經(jīng)廣泛應(yīng)用于Internet網(wǎng)絡(luò)中,同時(shí)也應(yīng)用于大多數(shù)計(jì)算機(jī)系統(tǒng),局域網(wǎng)和廣域網(wǎng)中。然而,隨著Internet 中的計(jì)算機(jī)數(shù)量突飛猛漲,IPv4 的局限性越發(fā)明顯:

1.IPv4地址數(shù)目面臨耗盡,日近緊張;

2.IPv4尋址并非完全分等級(jí),這使得Internet 樞紐路由器必須維持大量的路由表,負(fù)擔(dān)過(guò)重。

3.IPv4的地址必須被靜態(tài)分配或通過(guò)配置協(xié)議(如:DHCP)進(jìn)行分配。IPv6的開(kāi)發(fā)目標(biāo)之一就是將提供更為簡(jiǎn)便的配置方案。

于是IPv6(6.0版本)應(yīng)運(yùn)而生。在Window系統(tǒng)中,Windows XP 提供了IPv6的developer-release版本;Windows 2000也可在http://www.microsoft.com/ipv6 下載 IPv6協(xié)議預(yù)覽。

一.IPv4地址及其尋址

1.IPv4地址

IPv4地址(常稱IP地址)用一個(gè)32位數(shù)表示;通常表示位十進(jìn)制格式,地址的每8位字節(jié)被表示轉(zhuǎn)為一個(gè)十進(jìn)制的數(shù)值,并由句點(diǎn)分隔,如:192.168.0.1;IPv4地址 通常分為A、B、C、D、E 五類。

2.IPv4尋址

在WiNSock 中,通過(guò)SOCKADDR_IN 結(jié)構(gòu)來(lái)指定IPv4的地址和服務(wù)斷口信息:

STruct sockaddr_in {

short sin_family ;//必須為AF_INET,表示使用IPv4地址簇

u_short sin_Port; //TCP/UDP 端口

struct in_addr sin_addr;// IP地址(以網(wǎng)絡(luò)字節(jié)順序排列, 4個(gè)字節(jié))

char sin_zero[8];//填充項(xiàng)

}

二.IPv6地址及其尋址

1.IPv6地址

IPv6地址與IPv4地址的顯著的不同是128位,長(zhǎng)度是IPv4地址的4倍。IPv6地址由16位字節(jié)分段表示,顯示為冒號(hào)分隔的十六進(jìn)制:

21DA:00D3:0000:2F3A:B234:ED12:9C5A:DAC3

IPv6地址的分配

分配

地址前綴

保留地址0000 0000

為NSAP預(yù)留0000 0001

可聚合的全球單播地址001

鏈接-本地單播地址1111 1110 10

站點(diǎn)-本地單播地址1111 1110 11

多播地址1111 1111

2. IPv6的尋址

Winsock中,尋址使用一下結(jié)構(gòu):

struct sockaddr_in6{

short sin6_family;// 地址簇:AF_INET6

u_short sin6_port;//端口號(hào)

u_lONg sin6_flowinfo;//連接標(biāo)記通信量

struct in6_addr sin6_addr;//16字節(jié)結(jié)構(gòu)的IPv6 地址

u_long sin6_scope_id;//地址所有的接口索引

}

三.獨(dú)立于協(xié)議的地址及名稱解析

由此可見(jiàn)在尋址時(shí),IPv4使用16字節(jié)的SOCK_ADDR_IN 結(jié)構(gòu),IPv6則使用28 字節(jié)的SOCK_ADDR_IN6 結(jié)構(gòu)。為了解決這個(gè)問(wèn)題,IPv6中引入了新的尋址函數(shù)。 [Page]

1.getaddrinfo(),它提供獨(dú)立于協(xié)議的名稱解析:

int getaddrinfo(

const char *FAR *nodenAME,

const char FAR* SERvname,

const struct addrinfo FAR *hins,

struct addrinfo FAR *FAR *res

);

l 第一參數(shù):nodename,以空字節(jié)結(jié)束的主機(jī)名或文字地址

l 第二參數(shù):servname,包含端口或服務(wù)名(如:FTP,TELNET)的以空字節(jié)結(jié)束的字符串

l 第三個(gè)參數(shù):hins 是一個(gè)結(jié)構(gòu)(addrinfo),包含名稱解析的執(zhí)行方式選項(xiàng)

l 第四個(gè)參數(shù):res ,用于返回 addrinfo 結(jié)構(gòu)的一個(gè)或多個(gè)鏈表

結(jié)構(gòu)addrinfo 的定義:

struct addrinfo{

int ai_flags;

int ai_family;

int ai_socktype;

int ai_protocol;

size_t ai_addrlen;

char *ai_cannoname;

struct sockaddr *ai_addr;

struct addrinfo *ai_next;

}

l ai_flags 選值:AI_PASSIVE:可以用來(lái)獲取能夠傳遞給bind函數(shù)的地址,此時(shí)nodename應(yīng)設(shè)置為NULL,servname為欲綁定的端口;AI _CANONNAME 表示nodename 是主機(jī)名;AI_NUMBERICHOST 表示, nodename 是一個(gè)文字字符串地址(如:“192.168.0.1”)

l ai_family 選值:AI_INET或PF_INET(IPv4地址簇);AI_INET6或PF_INET6(IPv6地址簇);AI_UNSPEC(未指定,可能是IPv4或IPv6 地址簇)

l ai_socktype選值:SOCK_DGRAM(UDP類型套接字);SOCK_STREAM (TCP類 型套接字)

l ai_protocol 選值:IPPROTO_TCP (TCP/IP協(xié)議)

如果函數(shù)解析成功,解析后的地址將通過(guò)res返回。如果名稱被解析為多個(gè)地址,則返回一個(gè)由ai_next 字段形成的鏈表。每個(gè)由名稱解析的地址在ai_addr中表示,長(zhǎng)度在ai_addrlen中表示。

2.getnameinfo()函數(shù)與getaddrinfo()相對(duì)應(yīng),功能相反。

. int getnameinfo(

const struct sockaddr FAR *sa,

socklen_t salen, [Page]

char FAR *host,

DWORD hostlen,

char FAR *serv,

DWORD servlen,

Int flags);

以上參數(shù)的含義比較明顯,不再一一說(shuō)明。

3.釋放函數(shù): freeaddrinfo(res);

四、兼容IPv4和IPv6的網(wǎng)絡(luò)程序設(shè)計(jì)

兼容IPv4和IPv6的網(wǎng)絡(luò)程序,顯然涉及到兩個(gè)部分:客戶機(jī)和服務(wù)器。

在Windows 網(wǎng)絡(luò)編程中,Winsock是一種標(biāo)準(zhǔn)的API(應(yīng)用程序接口),Winsock2版本已經(jīng)發(fā)展成獨(dú)立于協(xié)議的的接口,被廣泛應(yīng)用于Windows平臺(tái)中。

<一>客戶機(jī)程序設(shè)計(jì)

對(duì)于客戶機(jī)來(lái)說(shuō),不管是建立TCP/UDP 連接,它都應(yīng)知道服務(wù)器的主機(jī)名或IP 地址,同時(shí)將服務(wù)器地址解析為IPv4或IPv6地址都可以,一般可以考慮一下步驟:

SOCKET s;

struct addrinfo,hints,*res=NULL;

char *szRemoteAddrESS;//主機(jī)名或IP 地址

char *szRemotePort;//端口號(hào)

int rc;

1.用getaddrinfo() 函數(shù)解析地址。hins結(jié)構(gòu)中 使用AF_UNSPEC標(biāo)志,便可以獲得地址簇類型(IPv4或IPv6)。

memset(&hintas,0,sizeof(hints));

hints.ai_family=AF_UNSPEC;

hints.ai_socktype=SOCK_STREAM;

hints.ai_protocol=IPPROTO_TCP;

rc=getaddrinfo(szRemoteAdddress,szRemotePort,&hints,&res);

if(rc==WSANO_DATA)

{// 無(wú)法解析,出錯(cuò)

}

用返回的addrinfo結(jié)構(gòu)中的ai_family,ai_socketype,ai_protocol字段來(lái)創(chuàng)建套接字。

s=Socket(res->ai_family,ai_socktype,res->protocol);

if(s==INVALID_SOCKET)

{//創(chuàng)建套接字失敗

}

2.使用返回的addrinfo結(jié)構(gòu)中的ai_addr來(lái)調(diào)用其他函數(shù)(connect(),send()等).。

rc==connect(s,res->ai_addr,res->addrlen);

if(rc==SOCKET_error)

{//連接失敗;

}

。。。//完成其他編程

<二>服務(wù)器程序設(shè)計(jì)

服務(wù)器程序設(shè)計(jì),應(yīng)考慮到IPv4和IPv6 都具有各自的堆棧;因此如果服務(wù)器希望能同時(shí)接受IPv4和IPv6的連接,就必須能同時(shí)創(chuàng)建IPv4和IPv6套接字;一般可以考慮一下步驟:

SOCKET socklisten[2];//*Socket變量

char *szPort=”8080”;//*端口

struct addinfo hints,*res=NULL,*ptr=NULL;

int rc,i=0;

1. 調(diào)用getaddrinfo()函數(shù),該結(jié)構(gòu)包含AI_PASSIVE,AF_UNSPEC標(biāo)志,以及所需的套接字類型、協(xié)議及所需的本地端口(用來(lái)*和接受數(shù)據(jù)等)。函數(shù)將返回的兩個(gè)addrinfo結(jié)構(gòu),分別可用于IPv4和IPv6*地址: [Page]

memset(&hints,0,sizeof(hints));

hints.ai_family=AF_UNSPEC;

hints.ai_socktype=SOCK_STREAM;

hints.ai_protocol=IPPROTO_TCP;

hints.ai_flags=AI_PASSIVE;

rc=getaddinfo(NULL,szPort,&hints,&res);

if(rc!=0){//失敗處理;}

ptr=res;

2. 用返回的addrinfo結(jié)構(gòu)中的ai_family,ai_socketype,ai_protocol字段來(lái)創(chuàng)建套接字后;便可以使用addrinfo結(jié)構(gòu)中的ai_addr 和ar_addrlen 字段調(diào)用綁定函數(shù)bind()。

while(ptr)

{

socklisten[i]=socket(ptr->ai_family,ptr->ai_socktype,ptr->ai_protocol);

if(socklisten[i]==INVALID_SOCKET){//創(chuàng)建失敗處理;}

rc=bind(socklisten[i],ptr->ai_addr,ptr->ai_addrlen);

if(rc==SOCKET_Error){//綁定失敗處理}

rc=listen(slisten[i],7)//開(kāi)始*

if(rc==SOCKET_ERROR){//*失敗處理}

i++;

ptr=ptr->ai_next;

}

。。。

//完成其他編程

五、程序?qū)嵗?/p>

在這里,給出一個(gè)基于IPV6的簡(jiǎn)單回應(yīng)(ECHO)服務(wù)器程序.

1.建立CIPv6 類

// IPv6.h: 頭文件,這里使用到了套接字中的“select I/O模型”

#define WIN32_LEAN_AND_MEAN

#include

#include

#include // IPv6 頭文件

#include

#include

#include

#pragma comment(lib, "ws2_32.lib")//套接字庫(kù)文件

#define DEFAULT_PORT "7274" // 默認(rèn)端口

#define BUFFER_SIZE 64 // 數(shù)據(jù)緩沖區(qū)

class CIPv6

{

public:

// 創(chuàng)建TCP 服務(wù)器

int CreateServer(char *Port = DEFAULT_PORT,char *Address = NULL);

void Usage(char *ProgName);//用戶信息提示

LPSTR DecodeError(int ErrorCode);//獲取錯(cuò)誤信息

CIPv6();

virtual ~CIPv6();

};

// IPv61.cpp: CIPv6類的實(shí)現(xiàn) .

// IPv61.cpp: implementation of the CIPv6 class.

//

//////////////////////////////////////////////////////////////////////

#include "stdafx.h"

#include "IPv61.h"

int CIPv6::CreateServer(char *Port, char *Address)

{

char Buffer[BUFFER_SIZE], Hostname[NI_MAXHOST];

int RetVal, FromLen, AmountRead;

SOCKADDR_STORAGE From;

WSADATA wsaData;

ADDRINFO Hints, *AddrInfo;

SOCKET ServSock;

fd_set SockSet;

// 啟動(dòng)Winsock

if ((RetVal = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0)

{

fprintf(stderr, "WSAStartup failed with error %d: %sn",

RetVal, DecodeError(RetVal));

WSACleanup();

return -1;

}

if (Port == NULL)

{

Usage("Port Error");

}

memset(&Hints, 0, sizeof(Hints));

Hints.ai_family =AF_INET6;// Family;

Hints.ai_socktype =SOCK_STREAM;

Hints.ai_flags = AI_NUMERICHOST | AI_PASSIVE;

RetVal = getaddrinfo(Address, Port, &Hints, &AddrInfo);

if (RetVal != 0)

{

fprintf(stderr, "getaddrinfo failed with error %d: %sn", RetVal, gai_strerror(RetVal));

WSACleanup();

return -1;

}

// 創(chuàng)建套接字

ServSock = socket(AddrInfo->ai_family,AddrInfo->ai_socktype, AddrInfo->ai_protocol);

if (ServSock == INVALID_SOCKET)

{

fprintf(stderr, "socket() failed with error %d: %sn",

WSAGetLastError(), DecodeError(WSAGetLastError()));

WSACleanup();

return -1;

}

// 綁定套接字

if (bind(ServSock, AddrInfo->ai_addr, AddrInfo->ai_addrlen) == SOCKET_ERROR)

{

fprintf(stderr,"bind() failed with error %d: %sn",

WSAGetLastError(), DecodeError(WSAGetLastError()));

WSACleanup();

return -1;

}

// 偵聽(tīng)

if (listen(ServSock, 5) == SOCKET_ERROR)

{

fprintf(stderr, "listen() failed with error %d: %sn",

WSAGetLastError(), DecodeError(WSAGetLastError()));

WSACleanup();

return -1;

}

printf("'Listening' on port %s, protocol %s, protocol family %sn",

Port, "TCP",

"PF_INET6");

freeaddrinfo(AddrInfo);

//使用select I/O 模型進(jìn)行收發(fā)

FD_ZERO(&SockSet);

while(1)

{

FromLen = sizeof(From);

if (FD_ISSET(ServSock, &SockSet)) break;

FD_SET(ServSock, &SockSet);

if (select(0, &SockSet, 0, 0, 0) == SOCKET_ERROR)

{

fprintf(stderr, "select() failed with error %d: %sn",

WSAGetLastError(), DecodeError(WSAGetLastError()));

WSACleanup();

return -1;

}

}

if (FD_ISSET(ServSock, &SockSet))

{

FD_CLR(ServSock, &SockSet);

}

//接受一個(gè)連接

SOCKET ConnSock;

ConnSock = accept(ServSock, (LPSOCKADDR)&From, &FromLen);

if (ConnSock == INVALID_SOCKET)

{

fprintf(stderr, "accept() failed with error %d: %sn",

WSAGetLastError(), DecodeError(WSAGetLastError()));

WSACleanup();

return -1;

}

if (getnameinfo((LPSOCKADDR)&From, FromLen, Hostname,

sizeof(Hostname), NULL, 0, NI_NUMERICHOST) != 0)

strcpy(Hostname, "");

printf("nAccepted connection from %sn", Hostname);

while(1)

{

//等待接受數(shù)據(jù)

AmountRead = recv(ConnSock, Buffer, sizeof(Buffer), 0);

if (AmountRead == SOCKET_ERROR)

{

fprintf(stderr, "recv() failed with error %d: %sn", WSAGetLastError(), DecodeError(WSAGetLastError()));

closesocket(ConnSock);

break;

}

if (AmountRead == 0) {

printf("Client closed connectionn");

closesocket(ConnSock);

break;

}

printf("Received %d bytes from client: [%.*s]n",

AmountRead, AmountRead, Buffer);

//進(jìn)行簡(jiǎn)單ECHO 回應(yīng)

printf("Echoing same data back to clientn");

RetVal = send(ConnSock, Buffer, AmountRead, 0);

if (RetVal == SOCKET_ERROR)

{

fprintf(stderr, "send() failed: error %d: %sn",

WSAGetLastError(), DecodeError(WSAGetLastError()));

closesocket(ConnSock);

break;

}

}

return 0;

}

void CIPv6::Usage(char *ProgName)

{

fprintf(stderr, "nSimple socket sample server program.n");

fprintf(stderr, "transport tEither TCP or UDP. (default: %s)n",

"TCP");

fprintf(stderr, "portttPort on which to bind. (default %s)n",

DEFAULT_PORT);

fprintf(stderr, "addresstIP address on which to bind.(default: unspecified address)n");

WSACleanup();

exit(1);

}

LPSTR CIPv6::DecodeError(int ErrorCode)

{

static char Message[1024];

FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |

FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, ErrorCode,

MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),

(LPSTR)Message, 1024, NULL);

return Message;

}

2.應(yīng)用示例

#include "stdafx.h"

#include "IPv6.h"

int main(int argc, char* argv[])

{

CIPv6 m_ipv6;

m_ipv6.CreateServer(); //采用默認(rèn)創(chuàng)建服務(wù)器,

//如果你成功安裝了IPv6可以使用正常使用

return 0;

}

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉