📄 usthread.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 + -