1 : 	////////////////////////////////////////////////////////////////////////
     2 : 	//
     3 : 	// FileName: csocket.cpp
     4 : 	//
     5 : 	// SOCKET関連
     6 : 	//
     7 : 	//
     8 : 	//制作日 02/08/10
     9 : 	//修正日 03/08/11
    10 : 	//
    11 : 	// 2002 Suika
    12 : 	
    13 : 	
    14 : 	
    15 : 	//#include "stdafx.h"
    16 : 	
    17 : 	#include <stdio.h>
    18 : 	#include <string.h>
    19 : 	#include "CSocket.h"
    20 : 	
    21 : 	/* wsock32.libをリンクする必要があります */
    22 : 	#ifdef WINDOWS
    23 : 	#ifndef _WIN32_WCE
    24 : 	#pragma comment(lib,"wsock32.lib ")
    25 : 	#else
    26 : 	#pragma comment(lib,"winsock.lib ")
    27 : 	#endif //end _WIN32_WCE
    28 : 	#endif //end WINDOWS
    29 : 	
    30 : 	//#define _DISPMESSAGE
    31 : 	//
    32 : 	
    33 : 	/*---------------------------------------------------------------------*/
    34 : 	// class CWinSock
    35 : 	/*---------------------------------------------------------------------*/
    36 : 	/*********************************************************
    37 : 	*	CWinSock()
    38 : 	*	コントラクタ CWinSockクラスが生成されたときに呼び出される
    39 : 	*********************************************************/
    40 : 	CWinSock::CWinSock()
    41 : 	{
    42 : 		m_fStartUp = FALSE;	//WinSockを初期化していない
    43 : 	}
    44 : 	
    45 : 	/*********************************************************
    46 : 	*	~CWinSock()
    47 : 	*	デストラクタ CWinSockクラスが解放されるときに呼ばれる
    48 : 	*********************************************************/
    49 : 	CWinSock::~CWinSock()
    50 : 	{
    51 : 		Release();			//解放する
    52 : 	}
    53 : 	
    54 : 	
    55 : 	/*********************************************************
    56 : 	*	Startup()
    57 : 	*	WinSockの初期化を行う
    58 : 	*	引数: mn = マイナーバージョン
    59 : 	*         mj = メジャーバージョン
    60 : 	* 戻り値: 成功:TRUE  失敗:FALSE
    61 : 	*********************************************************/
    62 : 	BOOL
    63 : 	CWinSock::Startup(BYTE mn,BYTE mj)
    64 : 	{
    65 : 	#ifdef WINDOWS
    66 : 		int nRC;
    67 : 		if(m_fStartUp) WSACleanup();
    68 : 		m_wVR = MAKEWORD(mn,mj);
    69 : 		nRC=WSAStartup(m_wVR,&m_wsdata);
    70 : 		if(m_wsdata.wVersion != m_wVR){//バージョンエラー
    71 : 			return FALSE;
    72 : 		}
    73 : 		if(nRC) return FALSE;
    74 : 	#endif
    75 : 		m_fStartUp = TRUE;
    76 : 		return TRUE;
    77 : 	}
    78 : 	
    79 : 	/*********************************************************
    80 : 	*	GetHostByName()
    81 : 	*	ホスト名からIPアドレス値を得る
    82 : 	*	引数: szHost = IPアドレスを受け取るポインタ(文字列)
    83 : 	*         nMaxCount = そのサイズ
    84 : 	*                     (IPアドレスが入るサイズでないと関数は失敗する)
    85 : 	*         szName = ホスト名
    86 : 	* 戻り値: 成功:TRUE  失敗:FALSE
    87 : 	*********************************************************/
    88 : 	BOOL
    89 : 	CWinSock::GetHostByName(LPSTR szHost,int nMaxCount,LPCSTR szName){
    90 : 		LPHOSTENT lpHost;
    91 : 		struct    in_addr addr;
    92 : 		szHost[0] = '\0';
    93 : 		// ホスト名を探す
    94 : 		lpHost = gethostbyname(szName);
    95 : 		if (lpHost == NULL)
    96 : 		{
    97 : 			return FALSE;//見つからなかった
    98 : 		}
    99 : 	
   100 : 		// アドレスの部分を取り出す
   101 : 		addr.s_addr = *((u_long FAR *) (lpHost->h_addr));
   102 : 	
   103 : 		//バッファサイズチェック
   104 : 		if((int)strlen(inet_ntoa(addr)) >= nMaxCount){
   105 : 			return FALSE;	//バッファが足りない
   106 : 		}
   107 : 	
   108 : 		//コピー
   109 : 		strcpy(szHost,inet_ntoa(addr));
   110 : 		return TRUE;
   111 : 	}
   112 : 	/*********************************************************
   113 : 	*	GetHostByAddr()
   114 : 	*	IPアドレスからホスト名を得る
   115 : 	*	引数: szName = ホスト名を受け取るポインタ(文字列)
   116 : 	*         nMaxCount = そのサイズ
   117 : 	*                     (アドレスが入るサイズでないと関数は失敗する)
   118 : 	*         szIPAddr = IPアドレス
   119 : 	* 戻り値: 成功:TRUE  失敗:FALSE
   120 : 	*********************************************************/
   121 : 	BOOL
   122 : 	CWinSock::GetHostByAddr(LPSTR szName,int nMaxCount,LPCSTR szIPAddr){
   123 : 		LPHOSTENT lpHost;
   124 : 		struct in_addr iaHost;
   125 : 		szName[0] = '\0';
   126 : 		iaHost.s_addr=inet_addr(szIPAddr);
   127 : 		lpHost = gethostbyaddr((const char *)&iaHost,sizeof(in_addr),AF_INET);
   128 : 		if(lpHost == NULL){
   129 : 			return FALSE;
   130 : 		}
   131 : 		//バッファサイズチェック
   132 : 		if((int)strlen(lpHost->h_name) >= nMaxCount){
   133 : 			return FALSE;	//バッファが足りない
   134 : 		}
   135 : 		strcpy(szName,lpHost->h_name);
   136 : 		return TRUE;
   137 : 	}
   138 : 	
   139 : 	/*********************************************************
   140 : 	*	Release()
   141 : 	*	WinSockを解放する
   142 : 	* 戻り値: TRUE
   143 : 	*********************************************************/
   144 : 	BOOL
   145 : 	CWinSock::Release(void){
   146 : 	#ifdef WINDOWS
   147 : 		if(m_fStartUp){
   148 : 			WSACleanup();
   149 : 		}
   150 : 	#endif
   151 : 		m_fStartUp = FALSE;
   152 : 		return TRUE;
   153 : 	}
   154 : 	/*---------------------------------------------------------------------*/
   155 : 	// class CSocket  初期化のためにCWinSockを継承している
   156 : 	/*---------------------------------------------------------------------*/
   157 : 	/*********************************************************
   158 : 	*	CSocket()
   159 : 	*	コントラクタ CSocketクラスが生成されたときに呼び出される
   160 : 	*********************************************************/
   161 : 	CSocket::CSocket(){
   162 : 	
   163 : 	}
   164 : 	
   165 : 	/*********************************************************
   166 : 	*	Connect()
   167 : 	*	ホストに接続する
   168 : 	*********************************************************/
   169 : 	BOOL
   170 : 	CSocket::Connect(LPSTR szHost,WORD nPort){
   171 : 		LPHOSTENT lpHost;
   172 : 		m_addr.sin_port = htons(nPort);
   173 : 		m_addr.sin_family = AF_INET;
   174 : 	
   175 : 	//
   176 : 	
   177 : 		if((m_addr.sin_addr.s_addr=inet_addr(szHost)) == INADDR_NONE){
   178 : 			if ((lpHost = gethostbyname (szHost)) == NULL){
   179 : 		//		wsprintf (szError, TEXT("Unable to get the host name. Error: %d"),
   180 : 		//		WSAGetLastError ());
   181 : 		//		MessageBox (NULL, szError, TEXT("Error"), MB_OK);
   182 : 		//		closesocket (m_ServerSock);
   183 : 				return FALSE;
   184 : 			}
   185 : 			memcpy(&m_addr.sin_addr, lpHost->h_addr,lpHost->h_length);
   186 : 		}
   187 : 	//
   188 : 	/*
   189 : 		lpHost = gethostbyname(szHost);
   190 : 		if (lpHost == NULL)
   191 : 		{
   192 : 	#ifdef _DISPMESSAGE
   193 : 			MessageBox(NULL,_T("gethostbyname()"),_T("Error"),NULL);
   194 : 	#endif
   195 : 			return FALSE;//名前が見つからなかった
   196 : 		}
   197 : 		m_addr.sin_addr.s_addr = *((u_long FAR *) (lpHost->h_addr));
   198 : 	*/
   199 : 	
   200 : 		m_socket = ::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
   201 : 		if (!IS_VALIDSOCKET(m_socket))
   202 : 		{
   203 : 	#ifdef _DISPMESSAGE
   204 : 			MessageBox(NULL,_T("socket()"),_T("Error"),NULL);
   205 : 	#endif
   206 : 			return FALSE;
   207 : 		}
   208 : 		int nRet = ::connect(m_socket,
   209 : 					(LPSOCKADDR)&m_addr,
   210 : 					sizeof(struct sockaddr));
   211 : 		if (nRet == SOCKET_ERROR)
   212 : 		{
   213 : 	#ifdef _DISPMESSAGE
   214 : 			MessageBox(NULL,_T("connect()"),_T("Error"),NULL);
   215 : 	#endif
   216 : 			return FALSE;
   217 : 		}
   218 : 		return TRUE;
   219 : 	}
   220 : 	
   221 : 	/*********************************************************
   222 : 	*	Close()
   223 : 	*	ソケットを閉じる
   224 : 	*********************************************************/
   225 : 	BOOL
   226 : 	CSocket::Close()
   227 : 	{
   228 : 		::shutdown(m_socket,2);
   229 : 	#ifdef WINDOWS
   230 : 		::closesocket(m_socket);
   231 : 	#else
   232 : 		::close(m_socket);
   233 : 	#endif
   234 : 		return TRUE;
   235 : 	}
   236 : 	
   237 : 	
   238 : 	/*********************************************************
   239 : 	*	GetHostname()
   240 : 	*	
   241 : 	*********************************************************/
   242 : 	char* 
   243 : 	CSocket::GetHostname(char* lpHostName,int iCount){
   244 : 	
   245 : 		LPHOSTENT lpHost;
   246 : 		lpHost = gethostbyaddr((const char *)&m_addr.sin_addr,sizeof(in_addr),AF_INET);
   247 : 		if(lpHost == NULL){
   248 : 			return FALSE;
   249 : 		}
   250 : 		//バッファサイズチェック
   251 : 		if((int)strlen(lpHost->h_name) >= iCount){
   252 : 			return NULL;	//バッファが足りない
   253 : 		}
   254 : 		strcpy(lpHostName,lpHost->h_name);
   255 : 		return lpHostName;
   256 : 	
   257 : 	}
   258 : 	/*********************************************************
   259 : 	*	GetHostaddr()
   260 : 	*	
   261 : 	*********************************************************/
   262 : 	char* 
   263 : 	CSocket::GetHostaddr(char* lpHost){
   264 : 		strcpy(lpHost,inet_ntoa(m_addr.sin_addr));
   265 : 		return lpHost;
   266 : 	}
   267 : 	/*********************************************************
   268 : 	*	SendData()
   269 : 	*	データ送信 (すべて送信できるまでブロッキング)
   270 : 	*********************************************************/
   271 : 	BOOL 
   272 : 	CSocket::SendData(LPVOID pData,int dwLen)
   273 : 	{
   274 : 		int bsend;
   275 : 		char *bufp;
   276 : 		bufp = (char*)pData;
   277 : 	
   278 : 		do{
   279 : 			bsend = ::send(m_socket,bufp,dwLen,0);
   280 : 			if(bsend==SOCKET_ERROR){
   281 : 				return FALSE;
   282 : 			}
   283 : 			bufp += bsend; dwLen -= bsend;
   284 : 		}while(dwLen>0);
   285 : 	
   286 : 		return TRUE;
   287 : 	}
   288 : 	/*********************************************************
   289 : 	*	SendString()
   290 : 	*	データ送信 (文字列を送信)
   291 : 	*********************************************************/
   292 : 	BOOL 
   293 : 	CSocket::SendStr(LPCSTR szStr)
   294 : 	{
   295 : 		this->SendData((LPVOID)szStr,strlen(szStr));
   296 : 		return TRUE;
   297 : 	}
   298 : 	/*********************************************************
   299 : 	*	RecvData()
   300 : 	*	データ受信 (指定バイト受信するまでブロック)
   301 : 	*********************************************************/
   302 : 	BOOL 
   303 : 	CSocket::RecvData(LPVOID pBuf,int dwLen,DWORD* pdwRecvLen)
   304 : 	{
   305 : 	
   306 : 		DWORD dwByteRecv=0;
   307 : 		char *point=(char*)pBuf;
   308 : 		int rread;
   309 : 		while(1){
   310 : 			rread=::recv(m_socket,point,dwLen-dwByteRecv,0);
   311 : 			if((rread)==SOCKET_ERROR || rread==0) {
   312 : 				break;
   313 : 			}
   314 : 			dwByteRecv += rread;
   315 : 			point = (char*)pBuf +  dwByteRecv;
   316 : 			if((DWORD)dwLen <= dwByteRecv) break;
   317 : 		}
   318 : 		if(dwByteRecv == 0) {
   319 : 			return FALSE;
   320 : 	
   321 : 		}
   322 : 		if(pdwRecvLen)
   323 : 			*pdwRecvLen = (DWORD)dwByteRecv;
   324 : 		return TRUE;
   325 : 	}
   326 : 	/*********************************************************
   327 : 	*	RecvDataOnce()
   328 : 	*	データ受信 (受信できるだけ受信する)
   329 : 	*********************************************************/
   330 : 	BOOL 
   331 : 	CSocket::RecvDataOnce(LPVOID pBuf,int dwLen,DWORD* pdwRecvLen)
   332 : 	{
   333 : 		DWORD dwByteRecv=0;
   334 : 		dwByteRecv=::recv(m_socket,(char*)pBuf,dwLen,0);
   335 : 		if(dwByteRecv == 0)  return FALSE;
   336 : 		if(pdwRecvLen)
   337 : 			*pdwRecvLen = (DWORD)dwByteRecv;
   338 : 		return TRUE;
   339 : 	}
   340 : 	/*********************************************************
   341 : 	*	RecvLine()
   342 : 	*	データ受信 (1行) サイズが足りない場合はエラー
   343 : 	*   データの最後に自動的に \0を追加する
   344 : 	*********************************************************/
   345 : 	BOOL 
   346 : 	CSocket::RecvLine(char* pBuf,int dwLen,DWORD* pdwRecvLen)
   347 : 	{
   348 : 		DWORD dwRecv;
   349 : 		*pdwRecvLen = 0;
   350 : 		int iCnt=0;
   351 : 		while(1){
   352 : 			if(!this->RecvData(pBuf,1,&dwRecv)) return FALSE;
   353 : 			*pdwRecvLen++;
   354 : 			
   355 : 			if(*pBuf == '\r'){
   356 : 				if(!this->RecvData(pBuf,1,&dwRecv)) return FALSE;
   357 : 				*pBuf = '\0';
   358 : 				break;
   359 : 			}else if(*pBuf == '\n'){
   360 : 				*pBuf = '\0';
   361 : 				break;
   362 : 			}
   363 : 	
   364 : 			pBuf++;
   365 : 			iCnt++;
   366 : 			if(iCnt >= dwLen-1) return FALSE;	//バッファサイズオーバー
   367 : 		}
   368 : 	
   369 : 		return TRUE;
   370 : 	}
   371 : 	
   372 : 	/*********************************************************
   373 : 	*	Listen()
   374 : 	*	接続を待機する
   375 : 	*********************************************************/
   376 : 	BOOL 
   377 : 	CSocket::Listen(WORD nPort)
   378 : 	{
   379 : 		int ret;
   380 : 		m_socket = ::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
   381 : 		if(!IS_VALIDSOCKET(m_socket)){
   382 : 			return FALSE;
   383 : 		}
   384 : 		m_addr.sin_port=htons(nPort);
   385 : 		m_addr.sin_family = AF_INET;
   386 : 	#ifdef WINDOWS
   387 : 		m_addr.sin_addr.S_un.S_addr = INADDR_ANY;
   388 : 	#endif
   389 : 		ret = ::bind(m_socket,
   390 : 			(LPSOCKADDR)&m_addr,
   391 : 			sizeof(struct sockaddr));
   392 : 		if(ret == SOCKET_ERROR){
   393 : 			::closesocket(m_socket);
   394 : 	
   395 : 			return FALSE;
   396 : 		}
   397 : 		ret = ::listen(m_socket,SOMAXCONN);
   398 : 		if(ret == SOCKET_ERROR){
   399 : 			::closesocket(m_socket);
   400 : 			return FALSE;
   401 : 		}
   402 : 	
   403 : 		return TRUE;
   404 : 	}
   405 : 	/*********************************************************
   406 : 	*	Accept()
   407 : 	*	接続を受け付ける
   408 : 	*********************************************************/
   409 : 	BOOL
   410 : 	CSocket::Accept(CSocket& soc)
   411 : 	{
   412 : 	#ifdef WINDOWS
   413 : 		int  nLen =sizeof(soc.m_addr);
   414 : 	#else
   415 : 		socklen_t nLen = sizeof(soc.m_addr);
   416 : 	#endif
   417 : 		soc.m_socket=::accept(m_socket,(LPSOCKADDR)&soc.m_addr,&nLen);
   418 : 		if(!IS_VALIDSOCKET(soc.m_socket)){
   419 : 	
   420 : 			return FALSE;
   421 : 		}
   422 : 	
   423 : 		return TRUE;
   424 : 	}
   425 : 	/*---------------------------------------------------------------------*/
   426 : 	// class CSocketUDP
   427 : 	/*---------------------------------------------------------------------*/
   428 : 	/*********************************************************
   429 : 	*	CSocketUDP()
   430 : 	*	コントラクタ
   431 : 	*********************************************************/
   432 : 	CSocketUDP::CSocketUDP(){
   433 : 		return;
   434 : 	}
   435 : 	
   436 : 	/*********************************************************
   437 : 	*	StartUDP()
   438 : 	*	UDPソケットを作る
   439 : 	* 	wLocalPort = 0のときは送信のみ
   440 : 	*	wServerPort = 0のときは受信のみ
   441 : 	*********************************************************/
   442 : 	BOOL CSocketUDP::StartUDP(WORD wLocalPort,LPCSTR szServer,WORD wServerPort){
   443 : 		m_socket = socket(PF_INET, SOCK_DGRAM, 0);
   444 : 		if(!IS_VALIDSOCKET(m_socket)){
   445 : 			return FALSE;
   446 : 		}
   447 : 	
   448 : 		m_ServerPort = wServerPort;
   449 : 	
   450 : 	
   451 : 		struct  sockaddr_in	 sockname;		/* ソケットのアドレス */
   452 : 	
   453 : 		if(wLocalPort){
   454 : 	
   455 : 			/* ソケットのアドレスの構造体にサーバのIPアドレスとポート番号を設定します */
   456 : 			sockname.sin_family	   = AF_INET;					/* インターネットの場合 */
   457 : 			sockname.sin_addr.s_addr  = INADDR_ANY;				/* 自分のIPアドレスを使うようにする */
   458 : 			sockname.sin_port	   = htons((unsigned short)wLocalPort);		/* ローカルのポート番号 */
   459 : 			memset(sockname.sin_zero,(int)0,sizeof(sockname.sin_zero));
   460 : 	
   461 : 	
   462 : 	
   463 : 			if(bind(m_socket,(struct sockaddr *)&sockname,sizeof(sockname)) == SOCKET_ERROR){
   464 : 				return FALSE;
   465 : 			}
   466 : 	
   467 : 		}
   468 : 	
   469 : 		if(szServer && wServerPort){
   470 : 	
   471 : 			struct hostent *serverhostent;	/* サーバのホスト情報を指すポインタ */
   472 : 	
   473 : 			/* svNameにドットで区切った10進数のIPアドレスが入っている場合、serveraddrに32bit整数のIPアドレスが返ります */
   474 : 			m_ServerAddr = inet_addr((char*)szServer);
   475 : 			if ((long)m_ServerAddr == -1) {
   476 : 	
   477 : 				/* サーバ名(svName)からサーバのホスト情報を取得します */
   478 : 				serverhostent = gethostbyname(szServer);
   479 : 	
   480 : 	
   481 : 	
   482 : 				if (serverhostent == NULL) {
   483 : 					return FALSE;
   484 : 				}else{
   485 : 					/* サーバのホスト情報からIPアドレスをserveraddrにコピーします */
   486 : 					m_ServerAddr = *((unsigned long *)((serverhostent->h_addr_list)[0]));
   487 : 				}
   488 : 			}
   489 : 		}
   490 : 	
   491 : 	
   492 : 		return TRUE;
   493 : 	}
   494 : 	
   495 : 	BOOL
   496 : 	CSocketUDP::SendTo(LPCSTR lpBuf,DWORD dwBufSize){
   497 : 	
   498 : 		struct  sockaddr_in	 serversockaddr;		/* サーバのアドレス */
   499 : 	
   500 : 		/* サーバのアドレスの構造体にサーバのIPアドレスとポート番号を設定します */
   501 : 		serversockaddr.sin_family	 = AF_INET;				/* インターネットの場合 */
   502 : 		serversockaddr.sin_addr.s_addr  = m_ServerAddr;				/* サーバのIPアドレス */
   503 : 		serversockaddr.sin_port	 = htons((unsigned short)m_ServerPort);		/* ポート番号 */
   504 : 		memset(serversockaddr.sin_zero,(int)0,sizeof(serversockaddr.sin_zero));
   505 : 	
   506 : 		if(sendto(m_socket, (char*)lpBuf, dwBufSize, 0,(struct sockaddr *)&serversockaddr,sizeof(serversockaddr)) == SOCKET_ERROR){
   507 : 			return FALSE;
   508 : 		}
   509 : 	
   510 : 		return TRUE;
   511 : 	}
   512 : 	
   513 : 	BOOL
   514 : 	CSocketUDP::RecvFrom(LPSTR lpBuf,DWORD dwBufSize,DWORD* pdwByteRecv){
   515 : 	
   516 : 	
   517 : 		int buf_len;		/* 受信したバイト数 */
   518 : 	
   519 : 		struct  sockaddr_in	 serversockaddr;		/* サーバのアドレス */
   520 : 	
   521 : 	#ifdef WINDOWS
   522 : 		int  sockaddr_size;
   523 : 	#else
   524 : 		socklen_t sockaddr_size ;
   525 : 	#endif
   526 : 		/* サーバを指定して文字列を受信します */
   527 : 		/* 受信した文字列は buf に入ります */
   528 : 		sockaddr_size = sizeof(serversockaddr);
   529 : 		buf_len = recvfrom(m_socket, lpBuf, dwBufSize , 0,(struct sockaddr *)&serversockaddr,&sockaddr_size);
   530 : 		if (buf_len == SOCKET_ERROR ){
   531 : 			return FALSE;
   532 : 		}
   533 : 		*pdwByteRecv=buf_len;
   534 : 		return TRUE;
   535 : 	};
   536 : 	
   537 : 	
   538 : 	BOOL CSocketUDP::Close(){
   539 : 		::closesocket(m_socket);
   540 : 		return TRUE;
   541 : 	};
   542 : 	
   543 : 	#ifndef NO_CPING
   544 : 	/*---------------------------------------------------------------------*/
   545 : 	// class CPing  初期化のためにCWinSockを継承している
   546 : 	/*---------------------------------------------------------------------*/
   547 : 	/*********************************************************
   548 : 	*	CPing()
   549 : 	*	コントラクタ CPingクラスが生成されたときに呼び出される
   550 : 	*********************************************************/
   551 : 	CPing::CPing()
   552 : 	{
   553 : 		//デフォルト値の代入
   554 : 		m_ucTTL = 0;
   555 : 		m_lTimeout_sec = 5;
   556 : 		m_lTimeout_usec = 0;
   557 : 		return;
   558 : 	}
   559 : 	
   560 : 	int
   561 : 	CPing::Ping(LPCSTR pstrHost)
   562 : 	{
   563 : 		SOCKET	  rawSocket;
   564 : 		LPHOSTENT lpHost;
   565 : 		struct    sockaddr_in saDest;
   566 : 		struct    sockaddr_in saSrc;
   567 : 		DWORD	  dwTimeSent;
   568 : 		DWORD	  dwElapsed;
   569 : 		u_char    cTTL;
   570 : 		int       nRet;
   571 : 	
   572 : 		// Create a Raw socket
   573 : 		rawSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
   574 : 		if (rawSocket == SOCKET_ERROR) 
   575 : 		{
   576 : 	
   577 : 			return CPING_SOCKETERROR;
   578 : 		}
   579 : 		
   580 : 		// Lookup host
   581 : 		lpHost = gethostbyname(pstrHost);
   582 : 		if (lpHost == NULL)
   583 : 		{
   584 : 			closesocket(rawSocket);
   585 : 			return CPING_DNSERROR;//ホスト無し
   586 : 		}
   587 : 		
   588 : 		// Setup destination socket address
   589 : 		saDest.sin_addr.s_addr = *((u_long FAR *) (lpHost->h_addr));
   590 : 		saDest.sin_family = AF_INET;
   591 : 		saDest.sin_port = 0;
   592 : 	
   593 : 	//	::wsprintf(m_pingIP,inet_ntoa(saDest.sin_addr));
   594 : 	
   595 : 	//#ifndef _UNICODE 
   596 : 		//TTL設定
   597 : 		if(m_ucTTL){
   598 : 			if (setsockopt(rawSocket, IPPROTO_IP, IP_TTL, (char *)&m_ucTTL, sizeof(m_ucTTL)) == SOCKET_ERROR)
   599 : 			{
   600 : 				closesocket(rawSocket);
   601 : 				return CPING_SETOPTERROR;
   602 : 			}
   603 : 		}
   604 : 	//#endif
   605 : 		// Send ICMP echo request
   606 : 		SendEchoRequest(rawSocket, &saDest);
   607 : 		// Use select() to wait for data to be received
   608 : 		nRet = WaitForEchoReply(rawSocket);
   609 : 		if (nRet == SOCKET_ERROR)
   610 : 		{
   611 : 			closesocket(rawSocket);
   612 : 			return CPING_SELECTERROR;
   613 : 		}
   614 : 		if (!nRet)
   615 : 		{
   616 : 			closesocket(rawSocket);
   617 : 			return CPING_TIMEOUT;
   618 : 		}
   619 : 	
   620 : 		// Receive reply
   621 : 		dwTimeSent = RecvEchoReply(rawSocket, &saSrc, &cTTL);
   622 : 		// Calculate elapsed time
   623 : 		dwElapsed = GetTickCount() - dwTimeSent;
   624 : 	
   625 : 		m_ucTTL = cTTL;					//TTL
   626 : 		m_iReplayTime = dwElapsed;		//応答時間
   627 : 	#ifdef _UNICODE 
   628 : 	//	::MultiByteToWideChar(,,,,,);
   629 : 	
   630 : 		::MultiByteToWideChar(CP_ACP, 0,
   631 : 	                          inet_ntoa(saSrc.sin_addr), -1,
   632 : 	                          m_szReplyHost, sizeof(m_szReplyHost)/sizeof(TCHAR));
   633 : 	
   634 : 	#else
   635 : 		::wsprintf(m_szReplyHost,inet_ntoa(saSrc.sin_addr));	//応答したホスト
   636 : 	#endif
   637 : 		nRet = closesocket(rawSocket);
   638 : 	
   639 : 		if(m_ucIcmpType == ICMP_ECHOREPLY){
   640 : 			return dwElapsed;		//エコーが返ってきた
   641 : 		}else{
   642 : 			return CPING_UNREACHED;	//エコー応答以外が帰ってきた
   643 : 		}
   644 : 	}
   645 : 	
   646 : 	
   647 : 	
   648 : 	
   649 : 	int CPing::SendEchoRequest(SOCKET s,LPSOCKADDR_IN lpstToAddr)
   650 : 	{
   651 : 		static ECHOREQUEST echoReq;
   652 : 		static nId = 1;
   653 : 		static nSeq = 1;
   654 : 		int nRet;
   655 : 	
   656 : 		// Fill in echo request
   657 : 		echoReq.icmpHdr.Type		= ICMP_ECHOREQ;
   658 : 		echoReq.icmpHdr.Code		= 0;
   659 : 		echoReq.icmpHdr.Checksum	= 0;
   660 : 		echoReq.icmpHdr.ID			= nId++;
   661 : 		echoReq.icmpHdr.Seq			= nSeq++;
   662 : 	
   663 : 	
   664 : 	
   665 : 	
   666 : 		// Fill in some data to send
   667 : 		for (nRet = 0; nRet < REQ_DATASIZEDEF; nRet++)
   668 : 			echoReq.cData[nRet] = ' '+nRet;
   669 : 	
   670 : 		// Save tick count when sent
   671 : 		echoReq.dwTime				= GetTickCount();
   672 : 	
   673 : 		// Put data in packet and compute checksum
   674 : 		echoReq.icmpHdr.Checksum = in_cksum((u_short *)&echoReq, sizeof(ECHOREQUEST));
   675 : 	
   676 : 		// Send the echo request
   677 : 		nRet = sendto(s,						/* socket */
   678 : 					 (LPSTR)&echoReq,			/* buffer */
   679 : 					 sizeof(ECHOREQUEST),
   680 : 					 0,							/* flags */
   681 : 					 (LPSOCKADDR)lpstToAddr, /* destination */
   682 : 					 sizeof(SOCKADDR_IN));   /* address length */
   683 : 	
   684 : 		if (nRet == SOCKET_ERROR)
   685 : 			return CPING_SOCKETERROR;
   686 : 		return (nRet);
   687 : 	}
   688 : 	
   689 : 	u_short CPing::in_cksum(u_short *addr, int len)
   690 : 	{
   691 : 		register int nleft = len;
   692 : 		register u_short *w = addr;
   693 : 		register u_short answer;
   694 : 		register int sum = 0;
   695 : 	
   696 : 		/*
   697 : 		 *  Our algorithm is simple, using a 32 bit accumulator (sum),
   698 : 		 *  we add sequential 16 bit words to it, and at the end, fold
   699 : 		 *  back all the carry bits from the top 16 bits into the lower
   700 : 		 *  16 bits.
   701 : 		 */
   702 : 		//全ての合計を求める
   703 : 		while( nleft > 1 )  {
   704 : 			sum += *w++;
   705 : 			nleft -= 2;
   706 : 		}
   707 : 	
   708 : 		/* mop up an odd byte, if necessary */
   709 : 		//奇数の長さの場合
   710 : 		if( nleft  ) {
   711 : 	//		u_short	u = 0;
   712 : 	
   713 : 	//		*(u_char *)(&u) = *(u_char *)w ;
   714 : 	//		sum += u;
   715 : 	
   716 : 			sum += *(u_short *)w;
   717 : 		}
   718 : 	
   719 : 		/*
   720 : 		 * add back carry outs from top 16 bits to low 16 bits
   721 : 		 */
   722 : 		sum = (sum >> 16) + (sum & 0xffff);	/* add hi 16 to low 16 */
   723 : 		//桁上がり分を足す
   724 : 	
   725 : 		sum += (sum >> 16);			/* add carry */
   726 : 		//足した結果の繰り上がりも足す
   727 : 	
   728 : 		answer = ~sum;				/* truncate to 16 bits */
   729 : 		return (answer);
   730 : 	}
   731 : 	int CPing::WaitForEchoReply(SOCKET s)
   732 : 	{
   733 : 		struct timeval Timeout;
   734 : 		fd_set readfds;
   735 : 	
   736 : 		readfds.fd_count = 1;
   737 : 		readfds.fd_array[0] = s;
   738 : 		Timeout.tv_sec = m_lTimeout_sec;
   739 : 	    Timeout.tv_usec = m_lTimeout_usec;
   740 : 	
   741 : 		return(select(1, &readfds, NULL, NULL, &Timeout));
   742 : 	}
   743 : 	
   744 : 	DWORD CPing::RecvEchoReply(SOCKET s, LPSOCKADDR_IN lpsaFrom, u_char *pTTL)
   745 : 	{
   746 : 		ECHOREPLY echoReply;
   747 : 		int nRet;
   748 : 		int nAddrLen = sizeof(struct sockaddr_in);
   749 : 	
   750 : 		// Receive the echo reply
   751 : 		nRet = recvfrom(s,					// socket
   752 : 						(LPSTR)&echoReply,	// buffer
   753 : 						sizeof(ECHOREPLY),	// size of buffer
   754 : 						0,					// flags
   755 : 						(LPSOCKADDR)lpsaFrom,	// From address
   756 : 						&nAddrLen);			// pointer to address len
   757 : 	
   758 : 		// Check return value
   759 : 		if (nRet == SOCKET_ERROR)
   760 : 			return CPING_SOCKETERROR;
   761 : 	
   762 : 	//	lpsaFrom->sin_addr
   763 : 	
   764 : 		// return time sent and IP TTL
   765 : 		*pTTL = echoReply.ipHdr.TTL;
   766 : 	
   767 : 		m_ucIcmpType = echoReply.echoRequest.icmpHdr.Type;//ICMPタイプ
   768 : 	
   769 : 		return(echoReply.echoRequest.dwTime);   		
   770 : 	}
   771 : 	#endif //NOPING
   772 : 	
   773 : 	#if defined(_WIN32_WCE_PSPC) 
   774 : 	#endif
   775 : 	
   776 : 	
   777 :