📄 socmfc.cpp
字号:
{
closesocket(m_hSocket);
m_hSocket = INVALID_SOCKET;
}
}
void CWSocket::Connect(const SOCKADDR* lpSockAddr, int nSockAddrLen)
{
//Validate our parameters
ASSERT(IsCreated()); //must have been created first
if (connect(m_hSocket, lpSockAddr, nSockAddrLen) == SOCKET_ERROR)
ThrowWSocketException();
}
void CWSocket::Connect(LPCTSTR lpszHostAddress, UINT nHostPort)
{
USES_CONVERSION;
//Validate our parameters
ASSERT(IsCreated()); //must have been created first
ASSERT(lpszHostAddress); //Must have a valid host
//Work out the IP address of the machine we want to connect to
LPSTR lpszAscii = T2A(const_cast<LPTSTR>(lpszHostAddress));
//Determine if the address is in dotted notation
SOCKADDR_IN sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons(static_cast<u_short>(nHostPort));
sockAddr.sin_addr.s_addr = inet_addr(lpszAscii);
//If the address is not dotted notation, then do a DNS
//lookup of it.
if (sockAddr.sin_addr.s_addr == INADDR_NONE)
{
LPHOSTENT lphost = gethostbyname(lpszAscii);
if (lphost != NULL)
sockAddr.sin_addr.s_addr = (reinterpret_cast<LPIN_ADDR>(lphost->h_addr))->s_addr;
else
ThrowWSocketException();
}
//Call the other version of Connect which does the actual work
Connect(reinterpret_cast<SOCKADDR*>(&sockAddr), sizeof(sockAddr));
}
#ifdef _WINSOCK2API_
void CWSocket::Connect(const SOCKADDR* lpSockAddr, int nSockAddrLen, DWORD dwConnectionTimeout, BOOL bResetToBlockingMode)
{
//Create an event to wait on
WSAEVENT hConnectedEvent = WSACreateEvent();
if (hConnectedEvent == WSA_INVALID_EVENT)
ThrowWSocketException();
//Setup event selection on the socket
if (WSAEventSelect(m_hSocket, hConnectedEvent, FD_CONNECT) == SOCKET_ERROR)
{
//Hive away the last error
DWORD dwLastError = GetLastError();
//Close the event before we return
WSACloseEvent(hConnectedEvent);
//Throw the exception that we could not setup event selection
ThrowWSocketException(dwLastError);
}
//Call the SDK "connect" function
int nConnected = connect(m_hSocket, lpSockAddr, nSockAddrLen);
if (nConnected == SOCKET_ERROR)
{
//Check to see if the call should be completed by waiting for the event to be signalled
DWORD dwLastError = GetLastError();
if (dwLastError == WSAEWOULDBLOCK)
{
DWORD dwWait = WaitForSingleObject(hConnectedEvent, dwConnectionTimeout);
if (dwWait == WAIT_OBJECT_0)
{
//Get the error value returned using WSAEnumNetworkEvents
WSANETWORKEVENTS networkEvents;
int nEvents = WSAEnumNetworkEvents(m_hSocket, hConnectedEvent, &networkEvents);
if (nEvents == SOCKET_ERROR)
{
//Hive away the last error
DWORD dwLastError = GetLastError();
//Close the event before we return
WSACloseEvent(hConnectedEvent);
//Throw the exception that we could not call WSAEnumNetworkEvents
ThrowWSocketException(dwLastError);
}
else
{
ASSERT(networkEvents.lNetworkEvents & FD_CONNECT);
//Has an error occured in the connect call
if (networkEvents.iErrorCode[FD_CONNECT_BIT] != ERROR_SUCCESS)
{
//Close the event before we return
WSACloseEvent(hConnectedEvent);
//Throw the exception that an error has occurred in calling connect
ThrowWSocketException(networkEvents.iErrorCode[FD_CONNECT_BIT]);
}
}
}
else
{
//Close the event before we return
WSACloseEvent(hConnectedEvent);
//Throw the exception that we could not connect in a timely fashion
ThrowWSocketException(ERROR_TIMEOUT);
}
}
else
{
//Close the event before we return
WSACloseEvent(hConnectedEvent);
//Throw the exception that the connect call failed unexpectedly
ThrowWSocketException(dwLastError);
}
}
//Remove the event notification on the socket
WSAEventSelect(m_hSocket, hConnectedEvent, 0);
//Destroy the event now that we are finished with it
WSACloseEvent(hConnectedEvent);
//Reset the socket to blocking mode if required
if (bResetToBlockingMode)
{
DWORD dwNonBlocking = 0;
if (ioctlsocket(m_hSocket, FIONBIO, &dwNonBlocking) == SOCKET_ERROR)
{
//Throw the exception that we could not reset the socket to blocking mode
ThrowWSocketException();
}
}
}
void CWSocket::Connect(LPCTSTR lpszHostAddress, UINT nHostPort, DWORD dwConnectionTimeout, BOOL bResetToBlockingMode)
{
USES_CONVERSION;
//Validate our parameters
ASSERT(IsCreated()); //must have been created first
ASSERT(lpszHostAddress); //Must have a valid host
//Work out the IP address of the machine we want to connect to
LPSTR lpszAscii = T2A(const_cast<LPTSTR>(lpszHostAddress));
//Determine if the address is in dotted notation
SOCKADDR_IN sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons(static_cast<u_short>(nHostPort));
sockAddr.sin_addr.s_addr = inet_addr(lpszAscii);
//If the address is not dotted notation, then do a DNS
//lookup of it.
if (sockAddr.sin_addr.s_addr == INADDR_NONE)
{
LPHOSTENT lphost = gethostbyname(lpszAscii);
if (lphost != NULL)
sockAddr.sin_addr.s_addr = (reinterpret_cast<LPIN_ADDR>(lphost->h_addr))->s_addr;
else
ThrowWSocketException();
}
//Call the other version of Connect which does the actual work
Connect(reinterpret_cast<SOCKADDR*>(&sockAddr), sizeof(sockAddr), dwConnectionTimeout, bResetToBlockingMode);
}
#endif //_WINSOCK2API_
int CWSocket::Receive(void* lpBuf, int nBufLen, int nFlags)
{
//Validate our parameters
ASSERT(IsCreated()); //must have been created first
int nReceived = recv(m_hSocket, static_cast<LPSTR>(lpBuf), nBufLen, nFlags);
if (nReceived == SOCKET_ERROR)
ThrowWSocketException();
return nReceived;
}
int CWSocket::ReceiveFrom(void* lpBuf, int nBufLen, SOCKADDR* lpSockAddr, int* lpSockAddrLen, int nFlags)
{
//Validate our parameters
ASSERT(IsCreated()); //must have been created first
int nReceived = recvfrom(m_hSocket, static_cast<LPSTR>(lpBuf), nBufLen, nFlags, lpSockAddr, lpSockAddrLen);
if (nReceived == SOCKET_ERROR)
ThrowWSocketException();
return nReceived;
}
int CWSocket::ReceiveFrom(void* lpBuf, int nBufLen, CString& sSocketAddress, UINT& nSocketPort, int nFlags)
{
//Validate our parameters
ASSERT(IsCreated()); //must have been created first
SOCKADDR_IN sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
int nSockAddrLen = sizeof(sockAddr);
int nResult = ReceiveFrom(lpBuf, nBufLen, reinterpret_cast<SOCKADDR*>(&sockAddr), &nSockAddrLen, nFlags);
nSocketPort = ntohs(sockAddr.sin_port);
sSocketAddress = inet_ntoa(sockAddr.sin_addr);
return nResult;
}
int CWSocket::Send(const void* pBuffer, int nBufLen, int nFlags)
{
ASSERT(IsCreated()); //must have been created first
int nSent = send(m_hSocket, static_cast<const char*>(pBuffer), nBufLen, nFlags);
if (nSent == SOCKET_ERROR)
ThrowWSocketException();
return nSent;
}
int CWSocket::SendTo(const void* lpBuf, int nBufLen, const SOCKADDR* lpSockAddr, int nSockAddrLen, int nFlags)
{
//Validate our parameters
ASSERT(IsCreated()); //must have been created first
int nSent = sendto(m_hSocket, static_cast<const char*>(lpBuf), nBufLen, nFlags, lpSockAddr, nSockAddrLen);
if (nSent == SOCKET_ERROR)
ThrowWSocketException();
return nSent;
}
int CWSocket::SendTo(const void* lpBuf, int nBufLen, UINT nHostPort, LPCTSTR lpszHostAddress, int nFlags)
{
//Validate our parameters
ASSERT(IsCreated()); //must have been created first
USES_CONVERSION;
//Determine if the address is in dotted notation
SOCKADDR_IN sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons((u_short)nHostPort);
if (lpszHostAddress == NULL)
sockAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
else
{
//If the address is not dotted notation, then do a DNS
//lookup of it.
LPSTR lpszAscii = T2A(const_cast<LPTSTR>(lpszHostAddress));
sockAddr.sin_addr.s_addr = inet_addr(lpszAscii);
if (sockAddr.sin_addr.s_addr == INADDR_NONE)
{
LPHOSTENT lphost = gethostbyname(lpszAscii);
if (lphost != NULL)
sockAddr.sin_addr.s_addr = (reinterpret_cast<LPIN_ADDR>(lphost->h_addr))->s_addr;
else
ThrowWSocketException();
}
}
return SendTo(lpBuf, nBufLen, reinterpret_cast<SOCKADDR*>(&sockAddr), sizeof(sockAddr), nFlags);
}
void CWSocket::IOCtl(long lCommand, DWORD* lpArgument)
{
//Validate our parameters
ASSERT(IsCreated()); //must have been created first
if (ioctlsocket(m_hSocket, lCommand, lpArgument) == SOCKET_ERROR)
ThrowWSocketException();
}
void CWSocket::Listen(int nConnectionBacklog)
{
//Validate our parameters
ASSERT(IsCreated()); //must have been created first
if (listen(m_hSocket, nConnectionBacklog) == SOCKET_ERROR)
ThrowWSocketException();
}
void CWSocket::ShutDown(int nHow)
{
//Validate our parameters
ASSERT(IsCreated()); //must have been created first
if (shutdown(m_hSocket, nHow) == SOCKET_ERROR)
ThrowWSocketException();
}
void CWSocket::Create(BOOL bUDP)
{
//Validate our parameters
ASSERT(!IsCreated()); //must not have been already created
if (bUDP)
Create(SOCK_DGRAM, 0, PF_INET);
else
Create(SOCK_STREAM, 0, PF_INET);
}
void CWSocket::Create(int nSocketType, int nProtocolType, int nAddressFormat)
{
//Validate our parameters
ASSERT(!IsCreated()); //must not have been already created
m_hSocket = socket(nAddressFormat, nSocketType, nProtocolType);
if (m_hSocket == INVALID_SOCKET)
ThrowWSocketException();
}
void CWSocket::ConnectViaSocks4(LPCTSTR lpszHostAddress, UINT nHostPort, LPCTSTR lpszSocksServer, UINT nSocksPort, DWORD dwConnectionTimeout)
{
USES_CONVERSION;
ASSERT(IsCreated()); //must have been created first
//connect to the proxy
Connect(lpszSocksServer, nSocksPort);
try
{
//Fill in a connection request packet
WSOCKET_SOCK4_CONNECT_REQUEST request;
request.VN = 4;
request.CD = 1;
request.DSTPORT = htons(static_cast<u_short>(nHostPort));
//Determine if the address is in dotted notation
LPSTR lpszAscii = T2A(const_cast<LPTSTR>(lpszHostAddress));
request.DSTIP.S_un.S_addr = inet_addr(lpszAscii);
//If the address is not dotted notation, then do a DNS
//lookup of it, since Socks 4 does not support DNS proxying
if (request.DSTIP.S_un.S_addr == INADDR_NONE)
{
LPHOSTENT lphost = gethostbyname(lpszAscii);
if (lphost != NULL)
request.DSTIP.S_un.S_addr = (reinterpret_cast<LPIN_ADDR>(lphost->h_addr))->s_addr;
else
ThrowWSocketException();
}
request.USERID[0] = 0;
Send(&request, sizeof(request));
//Wait for the connection reply
WSOCKET_SOCKS4_CONNECT_REPLY reply;
memset(&reply, 0, sizeof(reply));
int nDataReceived = 0;
while (nDataReceived < sizeof(reply))
{
if (IsReadible(dwConnectionTimeout))
{
int nData = Receive((reinterpret_cast<BYTE*>(&reply)) + nDataReceived, sizeof(reply) - nDataReceived);
nDataReceived += nData;
}
else
ThrowWSocketException(WSAETIMEDOUT);
}
//Validate the response
if ((reply.VN != 0) || (reply.CD != 90))
ThrowWSocketException(ERROR_BAD_NET_RESP);
}
catch(CWSocketException* pEx)
{
//Close the socket before we rethrow the exception
int nError = pEx->m_nError;
pEx->Delete();
Close();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -