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

📄 usthread.cpp

📁 nucleus source 源码 全部源码
💻 CPP
字号:
/****************************************************************************/
/* FILE         		    												*/
/*																			*/
/*  USThread.cpp                                                            */    
/*																			*/
/* DESCRIPTION																*/
/*										   									*/
/*  Contains functions that allow the user to implement a Winsock UDP       */
/*  Server.                                                                 */
/*																			*/
/****************************************************************************/

#include "stdafx.h"
#include "nunetdem.h"
#include "NuNetDemDlg.h"
#include "USThread.h"
#include "winsock.h"
#include "SockUtil.h"

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

/////////////////////////////////////////////////////////////////////////////
// CUdpServerThread

//IMPLEMENT_DYNCREATE(CUdpServerThread, CWinThread)
IMPLEMENT_DYNAMIC(CUdpServerThread, CWinThread)


/****************************************************************************/
/* FUNCTION         														*/
/*																			*/
/*  CUdpServerThread::CUdpServerThread                                      */
/*																			*/
/* DESCRIPTION																*/
/*										   									*/
/*  Starts the Thread.                                                      */
/*																			*/
/****************************************************************************/

CUdpServerThread::CUdpServerThread(CNuNetDemDlg * pWnd)
{
	pDlgWnd = pWnd;

	// kill event starts out in the signaled state
	m_hEventKill = CreateEvent(NULL, TRUE, FALSE, NULL);
	m_hEventDead = CreateEvent(NULL, TRUE, FALSE, NULL);

}

/****************************************************************************/
/* FUNCTION         														*/
/*																			*/
/*  CUdpServerThread::~CUdpServerThread                                     */
/*																			*/
/* DESCRIPTION																*/
/*										   									*/
/* Ends the thraed.                                                         */
/*																			*/
/****************************************************************************/

CUdpServerThread::~CUdpServerThread()
{
	CloseHandle(m_hEventKill);
	CloseHandle(m_hEventDead);

}

/****************************************************************************/
/* FUNCTION         														*/
/*																			*/
/*  CUdpServerThread::InitInstance                                          */
/*																			*/
/* DESCRIPTION																*/
/*										   									*/
/*  Initializes the Thread.                                                 */
/*																			*/
/****************************************************************************/

BOOL CUdpServerThread::InitInstance()
{

	// TODO:  perform and per-thread initialization here
	//AfxMessageBox("UDP Server Thread Running");

	CNuNetDemDlg::c_lBytesUDPServe = 0;

	// UDP Server
	UpdateByteCount();

	return TRUE;
}

/****************************************************************************/
/* FUNCTION         														*/
/*																			*/
/*  CUdpServerThread::ExitInstance                                          */
/*																			*/
/* DESCRIPTION																*/
/*										   									*/
/*  Handles Cleaning up of the the Thread.                                  */
/*																			*/
/****************************************************************************/

int CUdpServerThread::ExitInstance()
{
	// TODO:  perform any per-thread cleanup here
	//AfxMessageBox("UDP Server Thread Stopped");

	return CWinThread::ExitInstance();
}

/****************************************************************************/
/* FUNCTION         														*/
/*																			*/
/*  CUdpServerThread::Delete                                                */
/*																			*/
/* DESCRIPTION																*/
/*										   									*/
/*  Deletes the Thread.                                                     */
/*																			*/
/****************************************************************************/

void CUdpServerThread::Delete()
{
	// acknowledge receipt of kill notification
	VERIFY(SetEvent(m_hEventDead));

	// calling the base Delete
	CWinThread::Delete();

}

/****************************************************************************/
/* FUNCTION         														*/
/*																			*/
/*  CUdpServerThread::KillThread                                            */
/*																			*/
/* DESCRIPTION																*/
/*										   									*/
/* Kills the Thread.                                                        */
/*																			*/
/****************************************************************************/

void CUdpServerThread::KillThread()
{
	// Note: this function is called in the context of other threads,
	//	not the thread itself.

	// reset the m_hEventKill which signals the thread to shutdown
	VERIFY(SetEvent(m_hEventKill));

	// allow thread to run at higher priority during kill process
	SetThreadPriority(THREAD_PRIORITY_ABOVE_NORMAL);
	WaitForSingleObject(m_hEventDead, INFINITE);
	//WaitForSingleObject(m_hThread, INFINITE);

	// now delete CWinThread object since no longer necessary
	//delete this;
}

BEGIN_MESSAGE_MAP(CUdpServerThread, CWinThread)
	//{{AFX_MSG_MAP(CUdpServerThread)
		// NOTE - the ClassWizard will add and remove mapping macros here.
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CUdpServerThread message handlers


/****************************************************************************/
/* FUNCTION         														*/
/*																			*/
/*  CUdpServerThread::UpdateByteCount                                       */
/*																			*/
/* DESCRIPTION																*/
/*										   									*/
/*  Performs the Winsock Implementation of a UDP Server.  It handles        */
/*  updating status, reception of data and sending of Data.                 */
/*																			*/
/****************************************************************************/

int CUdpServerThread::UpdateByteCount()
{

	char		InBuf [buflength];			/*input buffer */
	WSADATA		stWSAData;					/* return data for Winsock startup */
	SOCKET		s;							/*socket handle */
	struct		sockaddr_in stLclAddr;		/*local address structure */
	struct		sockaddr    rmtaddr;		/*remote addr structure */
	int			portspec = 0;
	int			nRet;
	int			bRet;                       /* bind return error value    */
	int			rRet;                       /* receive returen error value*/
	int			snRet;                      /* send return error value    */
	int			clRet;                      /* close return error value   */

	int			structlen=sizeof(rmtaddr);  /*length of structure for calls  */
	int			nBytesToXfer;               /*bytes to transfer for send function*/
	unsigned long ulTotalBytes = 0;
	CString		sNumBytes;
	CString		sStatus;
	CSockUtil	sockUtil;					/* WinSock Error Messages */
    long        Packet_num=0;
    unsigned long  ulPacket_num = 0;
  	// Initialize Winsock
    nRet = WSAStartup(0x0101, &stWSAData); /*get version 1.1 */
	if (nRet != 0)
	{
	   AfxMessageBox("Winsock startup error\n");  /*can't call GetLastError */
	   return 1;
	}
    
	// Ask for a udp socket
    s = socket(PF_INET, SOCK_DGRAM, 0);  /*ask for a udp socket*/

    if (s == INVALID_SOCKET) 
	{
        sStatus.Format("Unable to get socket- error msg %d\n", WSAGetLastError());
		AfxMessageBox(sStatus);			   
	}

	  // Setup the Local Socket Address Structure
      stLclAddr.sin_family = PF_INET;  
	  stLclAddr.sin_port = htons(pDlgWnd->m_Port);
      stLclAddr.sin_addr.s_addr =INADDR_ANY;
  


	// Bind
    bRet = bind(s,                          
	       (struct sockaddr FAR *)&stLclAddr,
	       sizeof(struct sockaddr));
    
	// Check for Binding Errors
    if (bRet == SOCKET_ERROR)
	{
        //sStatus.Format("Unable to bind socket- error %d\n", WSAGetLastError());
        sStatus.Format("Unable to bind socket - %s\n",sockUtil.SockerrToString(WSAGetLastError() ) );

		AfxMessageBox(sStatus);

		// Close the Socket
		closesocket(s);
    
		// Finished with Winsock
		WSACleanup();                        

		return (1);
	}
    while(1)
    {
	// Initialize the input buffer
	InBuf[0] = '\0';
    Packet_num = 0;
	// Wait for an event to signal stop looping
	while ( ((WaitForSingleObject(m_hEventKill, 0) != WAIT_OBJECT_0)) || 
			( !lstrcmp(InBuf,"quiting") ) )
	{
		memset(InBuf, 0, buflength);

		// Wait to receive a string buffer
		rRet = recvfrom(s,					/*the recfrom() stores the sockaddr */
		   InBuf,							/*needed for the sendto()      */
		   buflength,						/*size of buffer */
		   0,								/*flags */
		   (struct sockaddr FAR *)&rmtaddr, /*structure to put */
		   &structlen);                     /*info into   */
    
		// Check for Receive Errors
		if (rRet == SOCKET_ERROR) 
		{
			sStatus.Format("Unable to recvfrom- erro number %d\n", WSAGetLastError());
			AfxMessageBox(sStatus);
		}

		//need length of InBuf
		nBytesToXfer = rRet;                  

		// Sends the string back 
		snRet = sendto(s,                      
				InBuf,
				nBytesToXfer,						/* how many bytes to send */
				0,									/* flags  */
				(struct sockaddr FAR *)&rmtaddr,	/* structure stuff */
				sizeof(rmtaddr));

    
		// Check for Send Errors
		if (snRet == SOCKET_ERROR) 
		{
			sStatus.Format("Unable to sendto- erro number %d\n", WSAGetLastError());
			AfxMessageBox(sStatus);	
		}

		// Update Total Bytes Received
		CNuNetDemDlg::c_lBytesUDPServe += nBytesToXfer;
		ulTotalBytes += nBytesToXfer;
		sNumBytes.Format("%u",ulTotalBytes);

		// Show the byte count.
		pDlgWnd->m_edBytesUDPServe.SetWindowText(sNumBytes);
        ulPacket_num = Packet_num; 
        sNumBytes.Format("%u",ulPacket_num + 1);
        pDlgWnd->m_edpcktUDPSEREVR.SetWindowText(sNumBytes);


        pDlgWnd->UpdateList(InBuf, Packet_num + 1, nBytesToXfer);                       


      Packet_num++;
	}

	/*  Send the Quit 'q' datagram.  */
	snRet = sendto(s,                      
				(char*)"quiting",
				8,									/* how many bytes to send */
				0,									/* flags  */
				(struct sockaddr FAR *)&rmtaddr,	/* structure stuff */
				sizeof(rmtaddr));

    Sleep(10);
	// Check for Send Errors
	if (snRet == SOCKET_ERROR) 
	{
		sStatus.Format("Unable to sendto Quit Cmd - %s\n",sockUtil.SockerrToString(WSAGetLastError() ) );
		AfxMessageBox(sStatus);	
	}

    }
	// Close the Socket
    clRet = closesocket(s);
    
	// Check for Closing Socket Errors
    if (clRet != 0)
	{
      sStatus.Format("Problem closing socket! - %s\n",sockUtil.SockerrToString(WSAGetLastError() ) );
      AfxMessageBox(sStatus);
	}
    clRet = closesocket(s);
    if (clRet != 0)
	{
      sStatus.Format("Problem closing socket! - %s\n",sockUtil.SockerrToString(WSAGetLastError() ) );
      AfxMessageBox(sStatus);
	}


  
    pDlgWnd->ToggleButtons(TRUE);

	// Finished with Winsock
    
    pDlgWnd->ToggleButtons(TRUE);

    WSACleanup();                        

    return(0);

 }    

 void CUdpServerThread::ResetSocket(int nSock)
{

	LINGER		lingerInfo;
	WSADATA		stWSAData;               /* return data for Winsock startup */
	int			nRet;                    /* startup      return error value */
	int			socketd = nSock;

	lingerInfo.l_onoff = 1;
	lingerInfo.l_linger = 0;

	setsockopt( socketd,SOL_SOCKET, SO_LINGER, (char*)&lingerInfo, sizeof(lingerInfo) );

	nRet = closesocket(socketd);       /*only use closesocket, no shutdown() */
        
    if (nRet != 0)            
        AfxMessageBox("Problem closing socket!"); 
    
    WSACleanup();                        /*De-register WinSock */

	// Initialize the Winsock
    nRet = WSAStartup(0x0101, &stWSAData);     /*stWSAData not looked at */



}


⌨️ 快捷键说明

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