基于C++中的IPv6網(wǎng)絡(luò)程序設(shè)計(jì)
五、程序?qū)嵗?p>在這里,給出一個(gè)基于IPV6的簡(jiǎn)單回應(yīng)(ECHO)服務(wù)器程序.
1.建立CIPv6 類(lèi)
// 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);//用戶(hù)信息提示
LPSTR DecodeError(int ErrorCode);//獲取錯(cuò)誤信息
CIPv6();
virtual ~CIPv6();
};
// IPv61.cpp: CIPv6類(lèi)的實(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;
}
評(píng)論