// MySocket.cpp: implementation of the CMySocket class.
//
// ------------------------------------
// * 程 序 名:MySocket.h
// * 包 名:网络套接字封装类
// * 功 能:封装网络地址
// * 依赖组件:头文件MySocket.h中的两个类
// * 作 者:fusx
// * 开发日期:2003/06/11
// * 修改日期:2004/06/06
// * 项目名称:
// * 版 权:
// ------------------------------------
////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MySocket.h"
#include <crtdbg.h>
#include <assert.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMySocket::CMySocket():m_hSocket(INVALID_SOCKET)
,m_nErrCode(0)
{
}
CMySocket::~CMySocket()
{
assert(m_hSocket == INVALID_SOCKET);
WSACleanup();
}
void CMySocket::operator =(SOCKET sck)
{
assert(m_hSocket == INVALID_SOCKET);
m_hSocket = sck;
}
//创建套接字
bool CMySocket::Create(int nType)
{
assert(m_hSocket == INVALID_SOCKET);
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData))
{
m_nErrCode = WSAGetLastError();
return false;
}
if((m_hSocket = socket(AF_INET, nType, 0)) == INVALID_SOCKET)
{
m_nErrCode = WSAGetLastError();
return false;
}
return true;
}
//绑定套接字
bool CMySocket::Bind(LPCSOCKADDR psa)
{
assert(m_hSocket != INVALID_SOCKET);
if(bind(m_hSocket, psa, sizeof(SOCKADDR)) == SOCKET_ERROR)
{
m_nErrCode = WSAGetLastError();
return false;
}
return true;
}
//侦听套接字
bool CMySocket::Listen()
{
assert(m_hSocket != INVALID_SOCKET);
if(listen(m_hSocket, 5) == SOCKET_ERROR)
{
m_nErrCode = WSAGetLastError();
return false;
}
return true;
}
//连接服务器
bool CMySocket::Connect(LPCSOCKADDR psa)
{
assert(m_hSocket != INVALID_SOCKET);
// should timeout by itself
if(connect(m_hSocket, psa, sizeof(SOCKADDR)) == SOCKET_ERROR)
{
m_nErrCode = WSAGetLastError();
return false;
}
return true;
}
//接受套接字
bool CMySocket::Accept(CMySocket& sConnect, LPSOCKADDR psa,int nSecs)
{
assert(m_hSocket != INVALID_SOCKET);
assert(sConnect.m_hSocket == INVALID_SOCKET);
//设置超时
if (nSecs !=0)
{
FD_SET fd = {1, m_hSocket};
TIMEVAL tv = {nSecs, 0};
if (select(0, &fd, NULL, NULL, &tv) == 0)
{
m_nErrCode = WSAETIMEDOUT;
return false;
}
}
//接收连接套接字
int nLengthAddr = sizeof(SOCKADDR);
sConnect.m_hSocket = accept(m_hSocket, psa, &nLengthAddr);
if(sConnect == INVALID_SOCKET)
{
m_nErrCode = WSAGetLastError();
return false;
}
return true;
}
//发送数据,返回值是发送出去的数据字节,不一定是全部数据
bool CMySocket::Send(const char* pch, const int nSize, int& nBytesSent,int nSecs)
{
assert(m_hSocket != INVALID_SOCKET);
//如果客户端取消了读数据,则返回值要小于nSize
FD_SET fd = {1, m_hSocket};
TIMEVAL tv = {nSecs, 0};
if (select(0, NULL, &fd, NULL, &tv) == 0)
{
m_nErrCode = WSAETIMEDOUT;
return false;
}
//
if((nBytesSent = send(m_hSocket, pch, nSize, 0)) == SOCKET_ERROR)
{
m_nErrCode = WSAGetLastError();
return false;
}
return true;
}
//发送全部指定的数据
bool CMySocket::Write(const char* pch, const int nSize, int nSecs)
{
assert(m_hSocket != INVALID_SOCKET);
//设置超时值
FD_SET fd = {1, m_hSocket};
TIMEVAL tv = {nSecs, 0};
if ( select(0, NULL, &fd, NULL, &tv) == 0)
{
m_nErrCode = WSAETIMEDOUT;
return false;
}
int nBytesSent = 0;
int nBytesThisTime;
const char* pch1 = pch;
do
{
nBytesThisTime = send(m_hSocket, pch, nSize, 0);
if ( nBytesThisTime == SOCKET_ERROR )
{
m_nErrCode = WSAGetLastError();
return false;
}
nBytesSent += nBytesThisTime;
pch1 += nBytesThisTime;
} while(nBytesSent < nSize);
return true;
}
//接受对方传来的数据,返回字节多少
//注意:如果套接字被关闭,则返回值为0字符
bool CMySocket::Receive(char* pch, const int nSize, int& nBytesReceived, int nSecs)
{
assert(m_hSocket != INVALID_SOCKET);
//设置超时
FD_SET fd = {1, m_hSocket};
TIMEVAL tv = {nSecs, 0};
if ( select(0, &fd, NULL, NULL, &tv) == 0)
{
m_nErrCode = WSAETIMEDOUT;
return false;
}
//
nBytesReceived = recv(m_hSocket, pch, nSize, 0);
if(nBytesReceived == SOCKET_ERROR)
{
m_nErrCode = WSAGetLastError();
return false;
}
return true;
}
/*
bool CMySocket::Read(char* pch, const int nSize,int nBytesRead,int nSecs)
{
assert( m_hSocket != INVALID_SOCKET);
FD_SET fd = {1,m_hSocket};
int nTimeout,nLeft=nBytesRead;
char *pTemp = pch;
do
{
if ( (nSecs==0) && (nMillSecs==0) )
nTimeout = select(0, &fd, NULL, NULL, NULL);
else
{
TIMEVAL tv = {nSecs,nMillSecs};
nTimeout = select(0, &fd, NULL, NULL, &tv);
}
if (nTimeout == 0)
{
nErrCode = WSAGetLastError();
return false;
}
//
int nBytesReceived = recv(m_hSocket, pTemp, nLeft, 0);
if(nBytesReceived == SOCKET_ERROR)
{
nErrCode = WSAGetLastError();
return false;
}
pTemp += nBytesReceived;
nLeft -= nBytesReceived;
} while(nLeft<=0);
return true;
}
*/
//接受数据报,返回接受到的数据字节
bool CMySocket::ReceiveDatagram( LPSOCKADDR psa,char* pch, const int nSize, int& nBytesReceived,int nSecs)
{
assert(m_hSocket != INVALID_SOCKET);
//设置超时
FD_SET fd = {1, m_hSocket};
TIMEVAL tv = {nSecs, 0};
if ( select(0, NULL, &fd, NULL, &tv) == 0)
{
m_nErrCode = WSAETIMEDOUT;
return false;
}
//接受的缓存空间应该大于全部的数据报
int nFromSize = sizeof(SOCKADDR);
nBytesReceived = recvfrom(m_hSocket,pch,nSize,0,psa,&nFromSize);
if(nBytesReceived == SOCKET_ERROR)
{
m_nErrCode = WSAGetLastError();
return false;
}
return true;
}
//发送数据报,返回发送出去的字节多少
bool CMySocket::SendDatagram(LPCSOCKADDR psa, const char* pch, const int nSize, int& nBytesSent, int nSecs)
{
assert(m_hSocket != INVALID_SOCKET);
//设置超时
FD_SET fd = {1, m_hSocket};
TIMEVAL tv = {nSecs, 0};
if ( select(0, NULL, &fd, NULL, &tv) == 0)
{
m_nErrCode = WSAETIMEDOUT;
return false;
}
//
nBytesSent = sendto(m_hSocket, pch, nSize, 0, psa, sizeof(SOCKADDR));
if(nBytesSent == SOCKET_ERROR)
{
m_nErrCode = WSAGetLastError();
return false;
}
return true;
}
//获取对方的套接字地址
bool CMySocket::GetPeerAddr(LPSOCKADDR psa)
{
assert(m_hSocket != INVALID_SOCKET);
//
int nLengthAddr = sizeof(SOCKADDR);
if(getpeername(m_hSocket, psa, &nLengthAddr) == SOCKET_ERROR)
return false;
return true;
}
//获取本地的套接字地址
bool CMySocket::GetSockAddr(LPSOCKADDR psa)
{
assert(m_hSocket != INVALID_SOCKET);
//
int nLengthAddr = sizeof(SOCKADDR);
if(getsockname(m_hSocket,psa,&nLengthAddr) == SOCKET_ERROR)
return false;
return true;
}
//static function
//根据名字获取主机地址
CSockAddr CMySocket::GetHostByName(const char* pchName,const USHORT ushPort/*=0*/)
{
SOCKADDR_IN sockTemp;
sockTemp.sin_family = AF_INET;
sockTemp.sin_port = htons(ushPort);
sockTemp.sin_addr.s_addr = 0;
hostent* pHostEnt = gethostbyname(pchName);
if(pHostEnt != NULL)
{
ULONG* pulAddr = (ULONG*) pHostEnt->h_addr_list[0];
sockTemp.sin_addr.s_addr = *pulAddr; //地址已经是网络字节顺序
}
return sockTemp;
}
//static function
//根据地址获取主机名
const char* CMySocket::GetHostByAddr(LPCSOCKADDR psa)
{
hostent* pHostEnt = gethostbyaddr((char*) &((LPSOCKADDR_IN) psa)
->sin_addr.s_addr, 4, PF_INET);
if(pHostEnt == NULL)
{
return NULL;
}
return pHostEnt->h_name; // caller shouldn't delete this memory
}
//static function
//获取本地计算机的IP及主机名
bool CMySocket::GetLocalHostInfo(LPTSTR strHostName,LPTSTR strHostIP)
{
// Get host name.
char hostname[256];
int res = gethostname(hostname,sizeof(hostname));
if (res != 0)
return false;
strcpy(strHostName, hostname);
// Get host info for hostname.
hostent* pHostent = gethostbyname(hostname);
if (pHostent==NULL)
return false;
// Parse the hostent information returned
hostent &he = *pHostent;
sockaddr_in sa;
memcpy( &sa.sin_addr.s_addr, he.h_addr_list[0],he.h_length );
//for (int nAdapter=0; he.h_addr_list[nAdapter]; nAdapter++)
//{
// memcpy ( &sa.sin_addr.s_addr, he.h_addr_list[nAdapter],he.h_length);
// // Output the machines IP Address.
// // TRACE("Address: %s\n", inet_ntoa(sa.sin_addr)); // display as string
//}
strcpy(strHostIP,inet_ntoa(sa.sin_addr));
return true;
}
//关闭套接字
bool CMySocket::Close()
{//如果已经关闭了,则调用本函数也不会出错。
if (INVALID_SOCKET == m_hSocket)
return true;
if(closesocket(m_hSocket) == SOCKET_ERROR)
{
m_nErrCode = WSAGetLastError();
return false;
}
m_hSocket = INVALID_SOCKET;
return true;
}
// 连接服务器
bool CMySocket::Connect(LPCTSTR strIP, int nPort)
{
assert(m_hSocket != INVALID_SOCKET);
// should timeout by itself
CSockAddr sa(strIP,nPort);
if(connect(m_hSocket, sa, sizeof(SOCKADDR)) == SOCKET_ERROR)
{
m_nErrCode = WSAGetLastError();
return false;
}
return true;
}
bool CMySocket::Bind(LPCTSTR strIP, int nPort)
{
assert(m_hSocket != INVALID_SOCKET);
CSockAddr sa(strIP,nPort);
if(bind(m_hSocket, sa, sizeof(SOCKADDR)) == SOCKET_ERROR)
{
m_nErrCode = WSAGetLastError();
return false;
}
return true;
}
//根据错误代码获取系统的出错字符串
bool CMySocket::GetErrorMessage(const int nErrCode, char *pErrMsg, int nMaxLen)
{
assert(pErrMsg != NULL);
LPVOID lpMsgBuf;
DWORD dwLen = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, nErrCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf, 0, NULL );
if (dwLen == 0)
{
pErrMsg[0] = 0;
return false;
}
else
{
if ( nMaxLen > (int)dwLen )
nMaxLen = (int)dwLen;
memcpy(pErrMsg,lpMsgBuf,nMaxLen-1);
pErrMsg[nMaxLen-2] = 0;
LocalFree( lpMsgBuf );
}
return true;
}
本文地址:http://com.8s8s.com/it/it24242.htm