📄 ysocket.h
字号:
#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 + -