#pragma once
// IPv6.h: 头文件,这里使用到了套接字中的“select I/O模型”
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <ws2tcpip.h>
//#include <tpipv6.h> // IPv6 头文件
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#pragma comment(lib, "ws2_32.lib")//套接字库文件
#define DEFAULT_PORT "7274" // 默认端口
#define BUFFER_SIZE 64 // 数据缓冲区
#include <iostream>
#include <boost/thread/thread.hpp>
#include <boost/bind.hpp>
class CIPv6
{
public:
// 创建TCP 服务器
int CreateServer(char *Port = DEFAULT_PORT,char *Address = NULL);
void Usage(char *ProgName);//用户信息提示
LPSTR DecodeError(int ErrorCode);//获取错误信息
CIPv6();
virtual ~CIPv6();
void RunServer(SOCKET ServSock);
boost::thread* pThd[10];
SOCKET ServSock[10];
SOCKADDR_STORAGE From;
};
#include "IPv6.h"
// IPv61.cpp: CIPv6类的实现 .
// IPv61.cpp: implementation of the CIPv6 class.
//
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;
// 启动Winsock
if ((RetVal = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0)
{
fprintf(stderr, "WSAStartup failed with error %d: %s
",
RetVal, DecodeError(RetVal));
WSACleanup();
return -1;
}
if (Port == NULL)
{
Usage("Port Error");
}
memset(&Hints, 0, sizeof(Hints));
Hints.ai_family =AF_UNSPEC/*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: %s
", RetVal, gai_strerror(RetVal));
WSACleanup();
return -1;
}
int i = 0;
while (AddrInfo)
{
// 创建套接字
ServSock[i] = socket(AddrInfo->ai_family,AddrInfo->ai_socktype, AddrInfo->ai_protocol);
if (ServSock[i] == INVALID_SOCKET)
{
fprintf(stderr, "socket() failed with error %d: %s
",
WSAGetLastError(), DecodeError(WSAGetLastError()));
WSACleanup();
return -1;
}
// 绑定套接字
if (bind(ServSock[i], AddrInfo->ai_addr, AddrInfo->ai_addrlen) == SOCKET_ERROR)
{
fprintf(stderr,"bind() failed with error %d: %s
",
WSAGetLastError(), DecodeError(WSAGetLastError()));
WSACleanup();
return -1;
}
// 侦听
if (listen(ServSock[i], 5) == SOCKET_ERROR)
{
fprintf(stderr, "listen() failed with error %d: %s
",
WSAGetLastError(), DecodeError(WSAGetLastError()));
WSACleanup();
return -1;
}
printf("'Listening' on port %s, protocol %s, protocol family socket=%d
",
Port, "TCP",
ServSock[i]);
AddrInfo=AddrInfo->ai_next;
i++;
//boost::thread thrd(boost::bind(&CIPv6::RunServer, this, ServSock));
//thrd.join();
//pThd[i] = new boost::thread(boost::bind(&CIPv6::RunServer, this, ServSock));
//pThd[i]->join();
//i++;
}
freeaddrinfo(AddrInfo);
////使用select I/O 模型进行收发
//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: %s
",
// WSAGetLastError(), DecodeError(WSAGetLastError()));
// WSACleanup();
// return -1;
// }
//}
//if (FD_ISSET(ServSock, &SockSet))
//{
// FD_CLR(ServSock, &SockSet);
//}
////接受一个连接
//SOCKET ConnSock;
//ConnSock = accept(ServSock, (LPSOCKADDR)&From, &FromLen);
//if (ConnSock == INVALID_SOCKET)
//{
// fprintf(stderr, "accept() failed with error %d: %s
",
// WSAGetLastError(), DecodeError(WSAGetLastError()));
// WSACleanup();
// return -1;
//}
//if (getnameinfo((LPSOCKADDR)&From, FromLen, Hostname,
// sizeof(Hostname), NULL, 0, NI_NUMERICHOST) != 0)
// strcpy(Hostname, "<unknown>");
//printf("
Accepted connection from %s
", Hostname);
//while(1)
//{
// //等待接受数据
// AmountRead = recv(ConnSock, Buffer, sizeof(Buffer), 0);
// if (AmountRead == SOCKET_ERROR)
// {
// fprintf(stderr, "recv() failed with error %d: %s
", WSAGetLastError(), DecodeError(WSAGetLastError()));
// closesocket(ConnSock);
// break;
// }
// if (AmountRead == 0) {
// printf("Client closed connection
");
// closesocket(ConnSock);
// break;
// }
// printf("Received %d bytes from client: [%.*s]
",
// AmountRead, AmountRead, Buffer);
// //进行简单ECHO 回应
// printf("Echoing same data back to client
");
// RetVal = send(ConnSock, Buffer, AmountRead, 0);
// if (RetVal == SOCKET_ERROR)
// {
// fprintf(stderr, "send() failed: error %d: %s
",
// WSAGetLastError(), DecodeError(WSAGetLastError()));
// closesocket(ConnSock);
// break;
// }
//}
//return 0;
}
void CIPv6::Usage(char *ProgName)
{
fprintf(stderr, "
Simple socket sample server program.
");
fprintf(stderr, "transport tEither TCP or UDP. (default: %s)
",
"TCP");
fprintf(stderr, "port Port on which to bind. (default %s)
",
DEFAULT_PORT);
fprintf(stderr, "address IP address on which to bind.(default: unspecified address)
");
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;
}
CIPv6::CIPv6()
{
}
CIPv6::~CIPv6()
{
}
void CIPv6::RunServer(SOCKET ServSock)
{
int RetVal, FromLen, AmountRead;
char Buffer[BUFFER_SIZE], Hostname[NI_MAXHOST];
/*SOCKADDR_STORAGE From; */
/* WSADATA wsaData;
ADDRINFO Hints, *AddrInfo;
SOCKET ServSock; */
fd_set SockSet;
printf("'Listening' on socket=%d
", ServSock);
FromLen = sizeof(From);
//使用select I/O 模型进行收发
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: %s
",
WSAGetLastError(), DecodeError(WSAGetLastError()));
WSACleanup();
return ;
}
}
if (FD_ISSET(ServSock, &SockSet))
{
FD_CLR(ServSock, &SockSet);
}
//接受一个连接
SOCKET ConnSock;
ConnSock = accept(ServSock, (LPSOCKADDR)&From, &FromLen);
if (ConnSock == INVALID_SOCKET)
{
fprintf(stderr, "accept() failed with error %d: %s
",
WSAGetLastError(), DecodeError(WSAGetLastError()));
WSACleanup();
return;
}
if (getnameinfo((LPSOCKADDR)&From, FromLen, Hostname,
sizeof(Hostname), NULL, 0, NI_NUMERICHOST) != 0)
strcpy(Hostname, "<unknown>");
printf("
Accepted connection from %s
", Hostname);
while(1)
{
//等待接受数据
AmountRead = recv(ConnSock, Buffer, sizeof(Buffer), 0);
if (AmountRead == SOCKET_ERROR)
{
fprintf(stderr, "recv() failed with error %d: %s
", WSAGetLastError(), DecodeError(WSAGetLastError()));
closesocket(ConnSock);
break;
}
if (AmountRead == 0) {
printf("Client closed connection
");
closesocket(ConnSock);
break;
}
printf("Received %d bytes from client: [%.*s]
",
AmountRead, AmountRead, Buffer);
//进行简单ECHO 回应
printf("Echoing same data back to client
");
RetVal = send(ConnSock, Buffer, AmountRead, 0);
if (RetVal == SOCKET_ERROR)
{
fprintf(stderr, "send() failed: error %d: %s
",
WSAGetLastError(), DecodeError(WSAGetLastError()));
closesocket(ConnSock);
break;
}
}
}