📄 csock.cpp
字号:
#include "stdhdrs.h"
#include "common.h"
#include "WSockRes.h"
#include "csock.h"
unsigned long CWinSock::m_ulCWinSockInitialized = 0;
BOOL CWinSock::m_bRegisteredWinSockMsgs = FALSE;
//CWinSock Constructor
//Initializes Winsock
//Your application should check m_eCurrentSocketState
//If m_eCurrentSocketState == eSocketUninitialized then Winsock could not be initialized
// == eWSStarted then Winsock was started but does not
// support the requested version
// == eWSInitialized then all is well
//
//If you compile with WS_USE_WINDOWS_MSGS then the constructor will also register
//the window messages, otherwise the constants in csock.h will be used
//
CWinSock::CWinSock(UINT uMajorVersion, UINT uMinorVersion)
{
WORD wVersionRequested;
int err;
//Since we currently have no socket, mark the CurrentSocket as Invalid
//and the current state as Uninitialized
m_sockCurrentSocket = INVALID_SOCKET;
m_eCurrentSocketState = eSocketUninitialized;
//When asked to create a socket we will default to AF_INET for the family
//and INADDR_ANY for the address
m_SockAddrIn.sin_family = AF_INET;
m_SockAddrIn.sin_addr.s_addr = INADDR_ANY;
#ifdef WS_USE_REGISTERED_MSGS
//If we wanted to used Registered Windows messages instead of constants
//we would add the code here
if (m_bRegisteredWinSockMsgs == FALSE){
m_uWSA_READ = RegisterWindowMessage("WSA_READ");
m_uWSA_WRITE = RegisterWindowMessage("WSA_WRITE");
m_uWSA_ACCEPT = RegisterWindowMessage("WSA_ACCEPT");
m_uWSA_CONNECT = RegisterWindowMessage("WSA_CONNECT");
m_uWSA_CLOSE = RegisterWindowMessage("WSA_CLOSE");
m_uWSA_OOB = RegisterWindowMessage("WSA_OOB");
m_bRegisteredWinSockMsgs = TRUE;
}
#endif
wVersionRequested = MAKEWORD(uMajorVersion,uMinorVersion);
//See if we can initialize Winsock
err = WSAStartup(wVersionRequested, &m_wsaData);
//If we couldn't initialize Winsock simply return (since we can't return a
//value from a constructor
if (err != 0){
PrintError();
return;
}
//Although we don't know if we can use this version yet,
//set m_eCurrentSocketState to eWSStarted so that our destructor will
//call WSACleanup
m_eCurrentSocketState = eWSStarted;
//LoByte is the Major version number and the HiByte is the minor
if (LOBYTE(m_wsaData.wVersion) != uMajorVersion ||
HIBYTE(m_wsaData.wVersion) != uMinorVersion){
return;
}
if (LOBYTE(wVersionRequested) < uMajorVersion ||
(LOBYTE(wVersionRequested) == uMajorVersion &&
HIBYTE(wVersionRequested) < uMinorVersion)){
return;
}
//Set the version number info to the version number we are using
m_wsaData.wVersion = MAKEWORD(uMajorVersion,uMinorVersion);
m_wsaData.wHighVersion = MAKEWORD(uMajorVersion,uMinorVersion);
#ifdef _WS_VERBOSE_API
WS_TRACE1(TEXT("WSAData Max sockets %u\n"),(LPCTSTR)m_wsaData.iMaxSockets);
WS_TRACE1(TEXT("WSAData Datagram size %u\n"),(LPCTSTR)m_wsaData.iMaxUdpDg);
WS_TRACE1(TEXT("WSAData Description %s\n"),m_wsaData.szDescription);
WS_TRACE1(TEXT("WSAData Status %s\n"),m_wsaData.szSystemStatus);
if (m_wsaData.lpVendorInfo == NULL)
WS_TRACE0("WSAData lpVendorInfo is NULL\n");
else
WS_TRACE0("WSAData lpVendorInfo is not NULL\n");
#endif
//The initialization was successful so set m_eCurrentSocketState to initialized
m_eCurrentSocketState = eWSInitialized;
//Increment a counter of the number of Winsock initializes (we must uninitialize
//until this is zero)
m_ulCWinSockInitialized++;
}
//CWinsock destructor
//Closes the socket if the socket is open
//Calls WSACleanup if Winsock was successfully started
//
CWinSock::~CWinSock()
{
//Close the socket if it's open
if (GetCurrentSocketState() == eSocketOpened)
closesocket();
//If Winsock was initialized we need to call WSACleanup
if (m_eCurrentSocketState != eSocketUninitialized)
WSACleanup();
//Decrement our counter
if (m_ulCWinSockInitialized > 0)
m_ulCWinSockInitialized--;
}
//The debug statement which follows is not terminated until the #endif at the end of
//this file
//
#ifdef _DEBUG
//Debug version of accept
//See CSock.h for variations on accept
SOCKET CWinSock::accept(SOCKET s, struct sockaddr FAR *addr, int FAR *addrlen)
{
#ifdef _WS_VERBOSE_API
WS_TRACE0("CWinSock::accept\n");
#endif
//Call the native Winsock accept statement
SOCKET sockRet = ::accept(s, addr,addrlen);
//Save the error returned from accept (if any)
m_iLastError = ::GetLastError();
if (sockRet == INVALID_SOCKET){
WS_TRACE0("accept error:");
PrintError(m_iLastError);
}
return sockRet;
}
//Debug version of bind
//See CSock.h for variations on bind
int CWinSock::bind(SOCKET s, const struct sockaddr FAR *name, int namelen)
{
#ifdef _WS_VERBOSE_API
WS_TRACE0("CWinSock::bind\n");
#endif
//Call the native Winsock bind statement
int iBind = ::bind(s, name, namelen);
//Save the returned error code if any
m_iLastError = ::GetLastError();
if (iBind == SOCKET_ERROR){
WS_TRACE0("bind error:");
PrintError(m_iLastError);
}
return iBind;
}
//Debug version of closesocket
//See Csock.h for variations on closesocket
int CWinSock::closesocket(SOCKET s)
{
#ifdef _WS_VERBOSE_API
WS_TRACE0("CWinSock::closesocket\n");
#endif
//Call the native Winsock closesocket statement
int iclose = ::closesocket(s);
//Save the last error code if any
m_iLastError = ::GetLastError();
if (iclose == SOCKET_ERROR){
WS_TRACE0("closesocket error:");
PrintError(m_iLastError);
} else {
//Change the state of the socket to closed if the
//socket was successfully closed
m_eCurrentSocketState = eSocketClosed;
}
return iclose;
}
//Debug version of connect
//See Csock.h for variations on connect
int CWinSock::connect(SOCKET s, const struct sockaddr FAR *name, int namelen)
{
#ifdef _WS_VERBOSE_API
WS_TRACE0("CWinSock::connect\n");
#endif
//Call the native Winsock connect statement
int iconnect = ::connect(s,name,namelen);
//Save the last error if any
m_iLastError = ::GetLastError();
if (iconnect == SOCKET_ERROR){
WS_TRACE0("connect error:");
PrintError(m_iLastError);
} else {
//Change the state of the socket to closed
//if the connect
m_eCurrentSocketState = eSocketClosed;
}
return iconnect;
}
//Debug version of getpeername
//See CSock.h for variations on getpeername
int CWinSock::getpeername(SOCKET s, struct sockaddr FAR* name, int FAR* namelen)
{
#ifdef _WS_VERBOSE_API
WS_TRACE0("CWinSock::getpeername\n");
#endif
int ipeername = ::getpeername(s,name,namelen);
m_iLastError = ::GetLastError();
if (ipeername == SOCKET_ERROR){
WS_TRACE0("getpeername error:");
PrintError(m_iLastError);
}
return ipeername;
}
//Debug version of getsockname
//See CSock.h for variations on getsockname
int CWinSock::getsockname(SOCKET s, struct sockaddr FAR*name, int FAR* namelen)
{
#ifdef _WS_VERBOSE_API
WS_TRACE0("CWinSock::getpeername\n");
#endif
int isockname = ::getsockname(s,name,namelen);
m_iLastError = ::GetLastError();
if (isockname == SOCKET_ERROR){
WS_TRACE0("getsockname error:");
PrintError(m_iLastError);
}
return isockname;
}
//Debug version of getsockopt
//See CSock.h for variations on getsockopt
int CWinSock::getsockopt(SOCKET s, int level, int optname, LPTSTR optval,
int FAR* optlen)
{
#ifdef _WS_VERBOSE_API
WS_TRACE0("CWinSock::getsockopt\n");
#endif
int isockopt = ::getsockopt(s,level,optname,optval,optlen);
m_iLastError = ::GetLastError();
if (isockopt == SOCKET_ERROR){
WS_TRACE0("getsockopt error:");
PrintError(m_iLastError);
}
return isockopt;
}
//Debug version of htonl (Host TO Network Long)
u_long CWinSock::htonl(u_long hostlong)
{
#ifdef _WS_VERBOSE_API
WS_TRACE0("CWinSock::htonl\n");
#endif
return ::htonl(hostlong);
}
//Debug version of htons (Host TO Network Short)
u_short CWinSock::htons(u_short hostshort)
{
#ifdef _WS_VERBOSE_API
WS_TRACE0("CWinSock::htons\n");
#endif
return ::htons(hostshort);
}
//Debug version of inet_addr
//CSock.h also provides an MFC definition which uses CString instead of LPCSTR
unsigned long CWinSock::inet_addr(LPCSTR cp)
{
#ifdef _WS_VERBOSE_API
WS_TRACE0("CWinSock::inet_addr\n");
#endif
return ::inet_addr(cp);
}
//Debug version of inet_ntoa
LPTSTR CWinSock::inet_ntoa(struct in_addr in)
{
#ifdef _WS_VERBOSE_API
WS_TRACE0("CWinSock::inet_ntoa\n");
#endif
return ::inet_ntoa(in);
}
//Debug version of ioctlsocket
//See CSock.h for variations on ioctlsocket
int CWinSock::ioctlsocket(SOCKET s, long cmd, u_long FAR* argp)
{
#ifdef _WS_VERBOSE_API
WS_TRACE0("CWinSock::ioctlsocket\n");
#endif
int iioctl = ::ioctlsocket(s,cmd, argp);
m_iLastError = ::GetLastError();
if (iioctl == SOCKET_ERROR){
WS_TRACE0("ioctlsocket error:");
PrintError(m_iLastError);
}
return iioctl;
}
//Debug version of listen
//See CSock.h for variations on listen
int CWinSock::listen(SOCKET s, int backlong)
{
#ifdef _WS_VERBOSE_API
WS_TRACE0("CWinSock::listen\n");
#endif
int ilisten = ::listen(s,backlong);
m_iLastError = ::GetLastError();
if (ilisten == SOCKET_ERROR){
WS_TRACE0("listen error:");
PrintError(m_iLastError);
}
return ilisten;
}
//Debug version of ntohl (Network TO Host Long)
u_long CWinSock::ntohl(u_long netlong)
{
#ifdef _WS_VERBOSE_API
WS_TRACE0("CWinSock::ntohl\n");
#endif
return ::ntohl(netlong);
}
//Debug version of ntohs (Network TO Host Short)
u_short CWinSock::ntohs(u_short netshort)
{
#ifdef _WS_VERBOSE_API
WS_TRACE0("CWinSock::ntohs\n");
#endif
return ::ntohs(netshort);
}
//Debug version of recv
//See CSock.h for variations of recv
int CWinSock::recv(SOCKET s, LPTSTR buf, int len, int flags)
{
#ifdef _WS_VERBOSE_API
WS_TRACE0("CWinSock::recv\n");
#endif
int irecv = ::recv(s,buf,len,flags);
m_iLastError = ::GetLastError();
if (irecv == SOCKET_ERROR){
WS_TRACE0("recv error:");
PrintError(m_iLastError);
}
return irecv;
}
//Debug version of recvfrom
//See CSock.h for variations of recvfrom
int CWinSock::recvfrom(SOCKET s, LPTSTR buf, int len, int flags,
struct sockaddr FAR *from, int FAR *fromlen)
{
#ifdef _WS_VERBOSE_API
WS_TRACE0("CWinSock::recvfrom\n");
#endif
int irecvfrom = ::recvfrom(s,buf,len,flags,from,fromlen);
m_iLastError = ::GetLastError();
if (irecvfrom == SOCKET_ERROR){
WS_TRACE0("recvfrom error:");
PrintError(m_iLastError);
}
return irecvfrom;
}
//Debug version of select
long CWinSock::select(int nfds, fd_set FAR* readfds,
fd_set FAR* writefds,
fd_set FAR* exceptfds,
const struct timeval FAR* timeout)
{
#ifdef _WS_VERBOSE_API
WS_TRACE0("CWinSock::select\n");
#endif
int iselect = ::select(nfds, readfds, writefds, exceptfds, timeout);
m_iLastError = ::GetLastError();
if (iselect == SOCKET_ERROR){
WS_TRACE0("select error:");
PrintError(m_iLastError);
}
return iselect;
}
//Debug version of send
//See CSock.h for variations of send
//See CSock.h for an MFC definition of send using a CString instead of an LPCSTR
int CWinSock::send(SOCKET s, LPCSTR buf, int len, int flags)
{
#ifdef _WS_VERBOSE_API
WS_TRACE0("CWinSock::send\n");
#endif
int isend = ::send(s,buf,len,flags);
m_iLastError = ::GetLastError();
if (isend == SOCKET_ERROR){
WS_TRACE0("send error:");
PrintError(m_iLastError);
}
return isend;
}
//Debug version of sendto
//See CSock.h for variations of sendto
//See CSock.h for an MFC definition of sendto using a CString instead of an LPCSTR
int CWinSock::sendto(SOCKET s, LPCSTR buf, int len, int flags,
const struct sockaddr FAR *to, int tolen)
{
#ifdef _WS_VERBOSE_API
WS_TRACE0("CWinSock::sendto\n");
#endif
int isendto = ::sendto(s,buf,len,flags,to,tolen);
m_iLastError = ::GetLastError();
if (isendto == SOCKET_ERROR){
WS_TRACE0("sendto error:");
PrintError(m_iLastError);
}
return isendto;
}
//Debug version of setsockopt
//See CSock.h for variations of setsockopt
int CWinSock::setsockopt(SOCKET s,int level, int optname, LPCSTR optval, int optlen)
{
#ifdef _WS_VERBOSE_API
WS_TRACE0("CWinSock::setsockopt\n");
#endif
int isockopt = ::setsockopt(s,level,optname,optval,optlen);
m_iLastError = ::GetLastError();
if (isockopt == SOCKET_ERROR){
WS_TRACE0("setsockopt error:");
PrintError(m_iLastError);
}
return isockopt;
}
//Debug version of shutdown
//See CSock.h for variations of shutdown
int CWinSock::shutdown(SOCKET s, int how)
{
#ifdef _WS_VERBOSE_API
WS_TRACE0("CWinSock::shutdown\n");
#endif
int ishutdown = ::shutdown(s,how);
m_iLastError = ::GetLastError();
if (ishutdown == SOCKET_ERROR){
WS_TRACE0("shutdown error:");
PrintError(m_iLastError);
} else {
m_eCurrentSocketState = eSocketClosed;
}
return ishutdown;
}
//Debug version of socket
//See CSock.h for default values of af, type, and protocol
//Also notice that m_sockCurrentSocket is set (which is used by other functions
// when you do not provide a socket) and the socket state is changed
SOCKET CWinSock::socket(int af, int type, int protocol)
{
#ifdef _WS_VERBOSE_API
WS_TRACE0("CWinSock::socket\n");
#endif
SOCKET sock = ::socket(af,type,protocol);
m_iLastError = ::GetLastError();
if (sock == INVALID_SOCKET){
WS_TRACE0("socket error:");
PrintError(m_iLastError);
} else {
m_sockCurrentSocket = sock;
m_eCurrentSocketState = eSocketOpened;
}
return sock;
}
//Debug version of gethostbyaddr
//See CSock.h for an MFC definition using CString instead of LPCSTR
PHOSTENT CWinSock::gethostbyaddr(LPCSTR addr, int len, int type)
{
#ifdef _WS_VERBOSE_API
WS_TRACE0("CWinSock::gethostbyaddr\n");
#endif
PHOSTENT phostent = ::gethostbyaddr(addr,len,type);
m_iLastError = ::GetLastError();
if (phostent == NULL){
WS_TRACE0("gethostbyaddr error:");
PrintError(m_iLastError);
}
return phostent;
}
//Debug version of gethostbyname
//See CSock.h for an MFC definition using CString instead of LPCSTR
PHOSTENT CWinSock::gethostbyname(LPCSTR name)
{
#ifdef _WS_VERBOSE_API
WS_TRACE0("CWinSock::gethostbyname\n");
#endif
PHOSTENT phostent = ::gethostbyname(name);
m_iLastError = ::GetLastError();
if (phostent == NULL){
WS_TRACE0("gethostbyname error:");
PrintError(m_iLastError);
}
return phostent;
}
//Debug version of gethostname
//See CSock.h for an MFC definition using CString instead of LPCSTR
int CWinSock::gethostname(LPTSTR name, int namelen)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -