分享
 
 
 

阻塞套接字类-CPP文件

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

// 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;

}

//staticfunction

//根据名字获取主机地址

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;

}

//staticfunction

//根据地址获取主机名

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;

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有