⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ysocket.h

📁 非常方便的网络Socket类
💻 H
📖 第 1 页 / 共 3 页
字号:
#if !defined(YSocket_INCLUDED)
#define YSocket_INCLUDED
// typedef YSocket<CString> CMySocket; //使用方法
/*
#include <afx.h>       //MFC 支持
#include <afxwin.h>    // MFC core and standard components
#include <afxext.h>    // MFC extensions
*/
#include <stdio.h>
#include <winsock2.h>
#pragma comment (lib,"Ws2_32.lib")
/*
struct linger {
    u_short    l_onoff;
    u_short    l_linger;
};
*/
//static struct linger lg = {0,0};
template <class STRING>
class YSocket
{
public:
	struct sockaddr tpserver;
 	int nSTP; 
	SOCKET m_hSocket;
	int SEQ;							//用来记录次序的,一般没有用,保留变量
	int SEQ2;
	int IsLive;						//判断此 sock 类是否处于活动状态
	enum {DEFAULT_TIMEOUT=60};	
	YSocket()
	{
		sfGetP = 0;
		isWSAStartup = 0 ;
		SEQ = 0;SEQ2 =0 ;	SHUT_MODE = SD_BOTH ;
		if(WSAStartup(MAKEWORD(2,2),&wsa)!=0){
			//初始化错误!
			STRING tp;tp.Format("WSAStartup.no.1:%s",GetErrorStr());
			throw tp ;	
		}
		isWSAStartup = 1;
		//下面的语句用来保证如果 IsLive 已经被激活(如果是静态变量则会发生)
		m_strIPADD = "";
		if(IsLive !=1){
			m_hSocket = NULL; 
			IsLive = 0;
		}
	};
	YSocket(SOCKET nSocket)
	{
		isWSAStartup = 0;		sfGetP = 0;
		SEQ = 0;SEQ2 =0 ;  SHUT_MODE = SD_BOTH ;
		if(WSAStartup(MAKEWORD(2,2),&wsa)!=0){
			//初始化错误!
			STRING tp;tp.Format("WSAStartup.no.2:%s",GetErrorStr());
			throw tp ;	
		}
		isWSAStartup = IsLive = 1;
		m_hSocket = nSocket;
		m_strIPADD = "";
	};
	~YSocket()
	{
		if(IsLive){
			try{
				if(nSTP == SOCK_STREAM){
					//char tpbuffer[1000];
					//Read(tpbuffer,1000,0);
					shutdown(m_hSocket,SD_BOTH);
					closesocket(m_hSocket);
				} 
			}catch(...){
				;
			}
		}
		if(isWSAStartup==1)WSACleanup();
	}
	int GetNPort(){
		if(!(sfGetP&2)){
			GetPort();
		}
		return PORT;
	}
  BOOL Attach(SOCKET s)
  {
    Close();
    Create();
    m_hSocket = s;
    return TRUE;
  }
  static SOCKET GetAConnectSocket(STRING sIp,int nPort)
  {
    WSADATA wsa;
    if(WSAStartup(MAKEWORD(2,2),&wsa)!=0){
      STRING tp;tp.Format("WSAStartup.no.1:%s",GetErrorStr());
			throw tp ;	
    }
    SOCKET s;
    if ( (s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET){
		  STRING tp;tp.Format("Create Socket Failed :%s",GetErrorStr());
		  throw tp ;
    }
	  SOCKADDR_IN server;
    server.sin_family = AF_INET;
    server.sin_port = htons(nPort);
	  if((server.sin_addr.s_addr=inet_addr(sIp)) == INADDR_NONE) {   // lpszHostAddress 不是*.*.*.*格式的IP地址
		  struct hostent *hp;          // 通过主机名获取主机地址
		  if((hp = gethostbyname(sIp)) != NULL) {
			  memcpy(&(server.sin_addr),hp->h_addr_list[0],hp->h_length);
			  server.sin_family = hp->h_addrtype;
		  }else {
			  STRING tp;tp.Format("Connect.no.2:%s",GetErrorStr());
			  throw tp ;
		  }
	  }
    if(connect(s,(struct sockaddr *) &server, sizeof(SOCKADDR)) == SOCKET_ERROR) {
		  STRING tp;tp.Format("Connect.no.1:%s",GetErrorStr());
		  throw tp ;
	  }
    return s;
  }
	void  Create(int nSocketType=SOCK_STREAM);
	virtual bool Accept(YSocket& rConnectedSocket,SOCKADDR* lpSockAddr = NULL);
	void Bind(UINT nSocketPort, LPCTSTR lpszSocketAddress = NULL,int mode=0);//可以直接用IP地址或域名
	void Bind (const SOCKADDR* lpSockAddr,int mode=0);
	BOOL Close(int mode = 1);
	void Connect(const SOCKADDR* lpSockAddr);
	void Connect(LPCTSTR lpszHostAddress, UINT nHostPort); //可以直接用IP地址或域名
	static STRING GetErrorStr();
	void Listen(int nConnectionBacklog=5);
	virtual int Receive(void* lpBuf,const int nBufLen, const int nSecs = DEFAULT_TIMEOUT); //例子参见2.5.2.3
	int ReceiveTest(void* lpBuf, const int nBufLen); //例子参见2.5.2.3
	int ReceiveFrom(void* lpBuf, const int nBufLen,const int nSecs = DEFAULT_TIMEOUT);
	int ReceiveFrom(void* lpBuf, const int nBufLen,LPCTSTR  pSocketAddress, UINT& rSocketPort,const int nSecs = DEFAULT_TIMEOUT); 
	int ReceiveFrom(void* lpBuf, const int nBufLen,SOCKADDR* lpSockAddr, const int nSecs);
	virtual int Send(const void* lpBuf, int nBufLen,const int nSecs = DEFAULT_TIMEOUT);
	int Read(void* lpBuf, int nBufLen,const int nSecs = DEFAULT_TIMEOUT,int mode = 0);
	int Write(const void* lpBuf, int nBufLen,const int nSecs = DEFAULT_TIMEOUT);
	int SendTo(const void* lpBuf, int nBufLen,UINT nHostPort, LPCTSTR lpszHostAddress, const int nSecs=DEFAULT_TIMEOUT);
	int SendTo(const void* lpBuf, int nBufLen,const SOCKADDR* lpSockAddr, const int nSecs=DEFAULT_TIMEOUT);
	int SendTo(const void* lpBuf, int nBufLen,const int nSecs=DEFAULT_TIMEOUT);
	//得到cmysock中ip的端口字符串
	static STRING GetPort(YSocket& pSock);
	STRING& GetPort();
	//得到cmysock中ip的地址字符串
	static STRING GetIpAdd(YSocket& pSock);
	//得到把域名解吸成ip的地址字符串
	static STRING GetIpAdd(STRING tpdomain);
  //得到制定的 socket 的本地地址和端口
  static STRING GetLocIpAdd(SOCKET s);
  static UINT GetLocPort(SOCKET s);
  STRING GetLocPort();
  STRING GetLocIpAdd();

	STRING GetIpAdd(int mode=0);//如果mode=1则强制得到
	YSocket& operator =(YSocket& tp);
	YSocket& operator =(YSocket* tp);
	friend YSocket;
private:
	WSADATA wsa;
	int SHUT_MODE ;
	int isWSAStartup ;	//是否初始化了 WSAStartup 
	STRING m_strPORT;			//记录远程端口
	STRING m_strIPADD;		//记录远程ip地址
  STRING m_strLocPORT;			//记录本地端口
	STRING m_strLocIPADD;		//记录本地ip地址
	UINT PORT;						//
  UINT LocPORT;
	int sfGetP;
	void GetSockAddr(sockaddr_in &sinAddress,LPCTSTR SocketAddress,UINT nSocketPort);
	int JugeTime(int nSecs=DEFAULT_TIMEOUT,int flag=1);
};
// stdafx.cpp : source file that includes just the standard includes
//	FILEPTOP.pch will be the pre-compiled header
//	stdafx.obj will contain the pre-compiled type information
template <class STRING>
void YSocket<STRING>::GetSockAddr(sockaddr_in &sinAddress,LPCTSTR SocketAddress,UINT nSocketPort)
{
	sinAddress.sin_family		= AF_INET ;
	sinAddress.sin_addr.s_addr	= inet_addr(SocketAddress);
	sinAddress.sin_port			= htons(nSocketPort);
}
template <class STRING>
int YSocket<STRING>::JugeTime(int nSecs,int flag)
{
	int ret;
	/*/
	FD_SET fdread,fdwrite,fdexcept;
	FD_ZERO(&fdread);			//将fdread清空
	FD_ZERO(&fdwrite);			//将fdwrite清空
	FD_ZERO(&fdexcept);			//fdexcept
	FD_SET(m_hSocket,&fdread);	// 把 sockFD 加入到 fdread 套接口中
	FD_SET(m_hSocket,&fdwrite); // 把 sockFD 加入到 fdwrite套接口中
	FD_SET(m_hSocket,&fdexcept); // 把 sockFD 加入到 fdexcept套接口中
	*/
	FD_SET	fd = {1, m_hSocket};
	if(nSecs==-1){
		switch (flag){
			case 1:
				ret=select(0, &fd,NULL,NULL,NULL);
				break;
			case 2:
				ret=select(0, NULL,&fd,NULL,NULL);
				break;
			case 3:
				ret=select(0, NULL,NULL,&fd,NULL);
				break;
		}

		if(ret==SOCKET_ERROR) {
			STRING tp;tp.Format("JugeTime.no.1:%s",GetErrorStr());
			throw tp ;	
		}
		//TRACE("ret=%d\n",ret);
		if(ret>0){
			return flag;
		}else if(ret==0){
			return 0;
		}
		return 0;
	}else{
		TIMEVAL tv = {nSecs, 0};
		//TRACE("m_hSocket=%d\n jugetime=%d\n",m_hSocket,nSecs);
			//ret=select(0, NULL,&fd,NULL,&tv);
			//ret=select(0, NULL,NULL,&fd,&tv);
		switch (flag)	{
		case 1:
			ret=select(0, &fd,NULL,NULL,&tv);
			break;
		case 2:
			ret=select(0, NULL,&fd,NULL,&tv);
			break;
		case 3:
			ret=select(0, NULL,NULL,&fd,&tv);
			break;
		}

		if(ret==SOCKET_ERROR) {
			STRING tp;tp.Format("JugeTime.no.1:%s",GetErrorStr());
			throw tp ;	
		}
		//TRACE("ret=%d\n",ret);
		if(ret>0){
			return flag;
		}else if(ret==0){
			return 0;
		}
		return 0;
	}
} 
template <class STRING>
bool YSocket<STRING>::Accept(YSocket& rConnectedSocket,
					   SOCKADDR* lpSockAddr )
{
	int len=sizeof(sockaddr);
	if(lpSockAddr==NULL){
		lpSockAddr=&rConnectedSocket.tpserver;
	}
	if(nSTP==SOCK_STREAM){
		if((rConnectedSocket.m_hSocket=accept(m_hSocket,lpSockAddr,&len))==INVALID_SOCKET){
			STRING tp;tp.Format("Accept.no.1:%s",GetErrorStr());
			throw tp ;	
		} 
		rConnectedSocket.nSTP = SOCK_STREAM;
		if(lpSockAddr!=&rConnectedSocket.tpserver){
			rConnectedSocket.tpserver=*lpSockAddr;
		}
		rConnectedSocket.IsLive=1;
		rConnectedSocket.sfGetP = 0;
		return 1;
	}else return 0;
}
//可以直接用IP地址或域名
template <class STRING>
void YSocket<STRING>::Bind(UINT nSocketPort, LPCTSTR lpszSocketAddress,int mode)
{	
	struct sockaddr_in sinAddress ;

	sinAddress.sin_family		= AF_INET ;
	if (lpszSocketAddress == NULL){
		sinAddress.sin_addr.s_addr	= ADDR_ANY;
	}else{
		sinAddress.sin_addr.s_addr	= inet_addr(lpszSocketAddress);
	}
	sinAddress.sin_port			= htons(nSocketPort);

	switch(mode){
	case 1:
		BOOL tp = TRUE;
		setsockopt(m_hSocket,SOL_SOCKET ,SO_REUSEADDR,(char*)&tp,sizeof(BOOL));
		break;
	}
	if (bind(m_hSocket,(sockaddr *)&sinAddress,sizeof(struct sockaddr_in)) == SOCKET_ERROR){
		STRING tp;tp.Format("Bind.no.1:%s",GetErrorStr());
		throw tp ;	
	}
	tpserver =*(SOCKADDR*)&sinAddress;
}

template <class STRING>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -