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

📄 wsocket.cpp

📁 简单的远程控制工具,分为服务器与客户斋,让你了解socket编程的知识.
💻 CPP
字号:
//////////////////////////////////////////////////////////////////////
//WYD's Socket
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "WSocket.h"
#include <TIME.H>
#include <stdio.h> 

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#define SD_RECEIVE      0x00
#define SD_SEND         0x01
#define SD_BOTH         0x02

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CWSocket::CWSocket()
{
	WSADATA wsaData;

	m_sSocket = NULL;
	m_bConnected = FALSE;
	m_sServer = NULL;
	m_bListened = FALSE;
	m_nServerPort = -1;
	m_hServerThread = NULL;

	m_bNeedClose = FALSE;
	m_bNeedCloseServer = FALSE;
	
	if(WSAStartup(0x202, &wsaData) == 0)
	{
		m_bWSAStartup = TRUE;
		err = 0;
	}
	else
	{
		m_bWSAStartup = FALSE;
		err = WSAGetLastError();
	}
	m_para.IsRun = FALSE;
}

CWSocket::CWSocket(SOCKET s)
{
	m_sSocket = NULL;
	m_bWSAStartup = FALSE;
	m_sServer = NULL;
	m_bListened = FALSE;
	m_nServerPort = -1;
	m_hServerThread = NULL;

	m_bNeedClose = FALSE;
	m_bNeedCloseServer = FALSE;
	
	m_bConnected = IsSockConnected(s);
	if(m_bConnected) m_sSocket = s;

	if(!m_bConnected)
	{
		WSADATA wsaData;
		if(WSAStartup(0x202, &wsaData) == 0)
		{
			m_bWSAStartup = TRUE;
			err = 0;
		}
		else
		{
			m_bWSAStartup = FALSE;
			err = WSAGetLastError();
		}
	}
}

CWSocket::operator=(SOCKET s)
{	
	if(IsSockConnected(s))
	{
		if(m_bConnected) Close();
		m_sSocket = s;
		m_bConnected = TRUE;
		m_bNeedClose = FALSE;
	}
}

CWSocket::~CWSocket()
{	
    SetTimeout(0);
	if(m_bNeedClose) Close();
	if(m_bNeedCloseServer) CloseServer();
	if(m_bWSAStartup) WSACleanup();
}

BOOL CWSocket::Connection(LPCSTR pstrHost, int nPort)
{
	if(m_bConnected) Close();

	LPHOSTENT lpHost;	
	struct sockaddr_in server;	

	//Lookup host
	lpHost = gethostbyname(pstrHost);
	if(lpHost == NULL) return FALSE;

	server.sin_family = AF_INET;
	server.sin_addr.s_addr = *((u_long FAR *)(lpHost->h_addr));
	server.sin_port=htons(nPort);

	m_sSocket = socket(AF_INET, SOCK_STREAM, 0);

	if(m_sSocket <= 0)
	{
		err = WSAGetLastError();
		return FALSE;
	}
//new 
int bNodelay = 1; 
//int err; 
err = setsockopt(m_sSocket,IPPROTO_TCP, TCP_NODELAY, 
                 (char *)&bNodelay, sizeof(bNodelay));//不采用延时算法 
if (err != NO_ERROR)
{
		err = WSAGetLastError();
		return FALSE;
}
	if(connect(m_sSocket, (LPSOCKADDR)&server, sizeof(SOCKADDR)) == SOCKET_ERROR) 
	{
		err = WSAGetLastError();
		closesocket(m_sSocket);
		m_sSocket = NULL;
		return FALSE;
	}
	
	m_bNeedClose = TRUE;
	m_bConnected = TRUE;
	return TRUE;
}

void CWSocket::Close()
{
    SetTimeout(0);
	if(!m_bConnected) return;
	if(m_sSocket == NULL) return;

//	shutdown(m_sSocket, SD_RECEIVE);
	shutdown(m_sSocket, SD_BOTH);
	Sleep(50);
	closesocket(m_sSocket);
	m_sSocket = NULL;
	m_bConnected = FALSE;
}

void CWSocket::CloseServer()
{
	if(!m_bListened) return;
	if(m_sServer == NULL) return;

//	shutdown(m_sServer, SD_RECEIVE);
	shutdown(m_sServer, SD_BOTH);
	Sleep(50);
	closesocket(m_sServer);
	m_sServer = NULL;
	m_bListened = FALSE;
}


DWORD CALLBACK CWSocket::TimeoutControl(LPVOID lpParm)
{
//	time_t stime = time(NULL);
	TPARA   *para = (TPARA *)lpParm;
	BOOL bTimeover = FALSE;
    para->IsRun = TRUE;
	while(!bTimeover)
	{
		if(para->bExit)
		{
			para->IsExit = TRUE;
			//return 0;
			goto Exit01;
		}

		Sleep(1);
		time_t ntime = time(NULL);
		if((ntime - para->sTime) > para->OutTime) bTimeover = TRUE;
	}

	if(para->bExit)
	{
		para->IsExit = TRUE;
//		return 0;
		goto Exit01;
	}

	if(para->s != NULL)
	{
		para->pbConnected[0] = FALSE;
		shutdown(para->s, SD_BOTH);
		Sleep(5);
		closesocket(para->s);
	}
Exit01:
	para->IsExit = TRUE;
	para->IsRun = FALSE;
	return 0;
}

BOOL CWSocket::SetTimeout(int timeout)
{
	HANDLE hThread;
	DWORD dwThreadId;
//	TPARA para;
    if (timeout == 0) //Exit
	{
      if(m_para.IsRun == FALSE) return TRUE;
	  m_para.bExit = TRUE;
      Sleep(15);
      while(!m_para.IsExit) Sleep(1);
	  return TRUE;
	}
	m_para.OutTime = timeout;
	m_para.sTime = time(NULL);
	m_para.s = m_sSocket;
	m_para.bExit = FALSE;
	m_para.IsExit = FALSE;
	m_para.pbConnected = &m_bConnected;
	if (m_para.IsRun == FALSE)
	{
	  hThread = CreateThread(NULL, NULL, TimeoutControl, (LPVOID)(&m_para), 0, &dwThreadId);
	  if (hThread == NULL) return FALSE;
	}
    return TRUE;
}
int CWSocket::ReadData(char FAR* buf, int len, int timeout)
{
	if(!m_bConnected || m_sSocket == NULL)
	{
		err = -1;
		return -1;
	}
/*
	HANDLE hThread;
	DWORD dwThreadId;
	TPARA para;

	para.OutTime = timeout;
	para.s = m_sSocket;
	para.bExit = FALSE;
	para.IsExit = FALSE;
	para.pbConnected = &m_bConnected;
	hThread = CreateThread(NULL, NULL, TimeoutControl, (LPVOID)(&para), 0, &dwThreadId);
	if (hThread == NULL) return -1;
*/

TIMEVAL tv01 = {0, 1};//1ms钟延迟,实际为0-10毫秒 
int nSelectRet; 
int nRet, nLen;
//int nErrorCode; 
FD_SET fdr = {1, m_sSocket}; 
for (;;)
{
   fdr.fd_count = 1;
   nSelectRet=select(0, &fdr, NULL, NULL, &tv01);//检查可读状态 
   if(SOCKET_ERROR==nSelectRet) 
   { 
     err=WSAGetLastError(); 
     //return -1;
	 nRet = -1;
	 goto Exit01;
   } 
//	nRet = recv(m_sSocket, buf, len, 0);
//	if(nRet == SOCKET_ERROR) err = WSAGetLastError();
//    break;

    nLen=len;
    while (nLen>0 && (nRet=recv(m_sSocket,buf,nLen,0))>0)
	{
            buf+=nRet;
            nLen-=nRet;
	}
    if (nLen < 0 || nRet <=0) 
	{
	    shutdown(m_sSocket, SD_RECEIVE);
		Sleep(5);
		closesocket(m_sSocket);
		//return -1;
		nRet = -1;
	    goto Exit01;
	}

	//return len;
	nRet = len;
	goto Exit01;

}//end for
Exit01:
/*
para.bExit = TRUE;
Sleep(15);
while(!para.IsExit) Sleep(1);
*/
return nRet;
}

int CWSocket::SendData(const char FAR *buf, int len, int timeout)
{
	if(!m_bConnected || m_sSocket == NULL)
	{
		err = -1;
		return -1;
	}

	if(!IsSockConnected(m_sSocket))
	{
		m_bConnected = FALSE;
		err = -1;
		return -1;
	}

TIMEVAL tv01 = {0, 1};//1ms钟延迟,实际为9-10毫秒 
int nSelectRet; 
int nRet;

//int nErrorCode; 
FD_SET fdw = {1, m_sSocket}; 
for (;;)
{
	fdw.fd_count = 1;
    nSelectRet=select(m_sSocket, NULL, NULL,&fdw, &tv01);//检查可写状态 
    if(SOCKET_ERROR==nSelectRet) 
	{ 
     err=WSAGetLastError(); 
	 return -1;
	} 
    nRet = send(m_sSocket, buf, len, 0);
	if(nRet == SOCKET_ERROR) 
	{
/*		err = WSAGetLastError();
	    shutdown(m_sSocket, SD_SEND);
	    Sleep(15);
	    closesocket(m_sSocket);
*/	}

	break;
}//end for
Sleep(15);
return nRet;
}

BOOL CWSocket::IsSockConnected(SOCKET s)
{
	int nRet = 0;
	struct fd_set Fd_Recv;
    struct timeval Time_Recv;

	memset(&Fd_Recv, 0, sizeof(struct fd_set));
    FD_CLR(s, &Fd_Recv); 
    FD_SET(s, &Fd_Recv); 
    Time_Recv.tv_sec = 0;
    Time_Recv.tv_usec = 0;

	nRet = select(s, &Fd_Recv, NULL, NULL, &Time_Recv);

    return (nRet == 0);
}

BOOL CWSocket::CreateServer(int port, int backlog)
{
	if(m_bListened == TRUE) CloseServer();

	struct	sockaddr_in local;

	//创建监听socket
    m_sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
    if(m_sServer == SOCKET_ERROR)
    {
        err = WSAGetLastError();
        return FALSE;
    }

	//添参数	
	local.sin_addr.s_addr = htonl(INADDR_ANY);
    local.sin_family = AF_INET;
    local.sin_port = htons(port);

	if(bind(m_sServer, (struct sockaddr *)&local, sizeof(local)) == SOCKET_ERROR)
    {
		err = WSAGetLastError();
		closesocket(m_sServer);
        return FALSE;
    }

	//开始侦听
    if(listen(m_sServer, backlog) != 0)
	{
		err = WSAGetLastError();
		closesocket(m_sServer);
        return FALSE;
    }

	m_nServerPort = port;
	m_bListened = TRUE;
	m_bNeedCloseServer = TRUE;

	return TRUE;
}

SOCKET CWSocket::Listen(char *ClientIP)
{
	if(!m_bListened) return -1;
	if(m_sServer == NULL) return -1;

	SOCKET	sClient;	
	int		iAddrSize;
	struct	sockaddr_in addr;

	iAddrSize = sizeof(addr);

	sClient = accept(m_sServer, (struct sockaddr *)&addr, &iAddrSize);
	
	if(sClient == SOCKET_ERROR)
	{
		err = WSAGetLastError();
        return SOCKET_ERROR;
    }

	if(ClientIP != NULL)
	{
		sprintf(ClientIP, "%d.%d.%d.%d", addr.sin_addr.S_un.S_un_b.s_b1, 
										 addr.sin_addr.S_un.S_un_b.s_b2,
										 addr.sin_addr.S_un.S_un_b.s_b3,
										 addr.sin_addr.S_un.S_un_b.s_b4);
	}

	return sClient;
}

BOOL CWSocket::StartServer(DEALPROC lpDealFunc)
{
	if(!m_bListened) return -1;
	if(m_sServer == NULL) return -1;

	DWORD dwThreadId;
	SERVERPARA *para;

	para = new SERVERPARA;
	para->s = m_sServer;
	para->port = m_nServerPort;
	para->lpDealFunc = lpDealFunc;

	m_hServerThread = CreateThread(NULL, 0, ServerProc, (LPVOID)(para), 0, &dwThreadId);

	if(m_hServerThread == NULL)
	{
		delete para;
		err = WSAGetLastError();
        return FALSE;
	}

	return TRUE;
}

BOOL CWSocket::StopServer()
{
	CloseServer();

	return TRUE;
}

DWORD CALLBACK CWSocket::ServerProc(LPVOID lpParm)
{
	SERVERPARA *para = (SERVERPARA*)lpParm;
	
	if(para == NULL) return -1;

	SOCKET		s = para->s;
	int			port = para->port;
	DEALPROC	lpDealFunc = para->lpDealFunc;
	delete para;

	SOCKET	sClient;	
	int		iAddrSize;
	struct	sockaddr_in addr;
	char	IP[32];
	HANDLE	hThread;
    DWORD	dwThreadId;
	DEALPARA *parac;

	iAddrSize = sizeof(addr);

	while(1)
	{
		sClient = accept(s, (struct sockaddr *)&addr, &iAddrSize);
		
		if(sClient == SOCKET_ERROR) break;

		sprintf(IP, "%d.%d.%d.%d", addr.sin_addr.S_un.S_un_b.s_b1, 
									   addr.sin_addr.S_un.S_un_b.s_b2,
									   addr.sin_addr.S_un.S_un_b.s_b3,
									   addr.sin_addr.S_un.S_un_b.s_b4);

		parac = new DEALPARA;
		memset(parac->IP, 0, sizeof(parac->IP));
		parac->s = sClient;
		parac->port = port;
		parac->lpDealFunc = lpDealFunc;
		memcpy(parac->IP, IP, strlen(IP));	

		//侦听到连接,开一个线程		
        hThread = CreateThread(NULL, 0, DealProc, (LPVOID)(parac), 0, &dwThreadId);

		if(hThread == NULL) delete parac;
	}

	return 0;
}

DWORD CALLBACK CWSocket::DealProc(LPVOID lpParm)
{
	DEALPARA *para = (DEALPARA*)lpParm;
	
	if(para == NULL) return -1;

	SOCKET		s = para->s;
	int			port = para->port;
	DEALPROC	lpDealFunc = para->lpDealFunc;
	char		IP[32];
	memcpy(IP, para->IP, sizeof(IP));
	delete para;

	try{lpDealFunc(s, port, IP);}catch(...){return -1;}

	return 0;
}

SOCKET CWSocket::GetSocket()
{
	return m_sSocket;
}

SOCKET CWSocket::GetServerSocket()
{
	return m_sServer;
}

int CWSocket::GetError()
{
	return err;
}

⌨️ 快捷键说明

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