📄 socmfc.cpp
字号:
Bind((SOCKADDR*) &sockAddr, sizeof(sockAddr));
}
void CWSocket::Close()
{
if (m_hSocket != INVALID_SOCKET)
{
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)
AfxThrowWSocketException();
}
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((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((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 = ((LPIN_ADDR)lphost->h_addr)->s_addr;
else
AfxThrowWSocketException();
}
//Call the other version of Connect which does the actual work
Connect((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)
AfxThrowWSocketException();
//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
AfxThrowWSocketException(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
AfxThrowWSocketException(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
AfxThrowWSocketException(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
AfxThrowWSocketException(ERROR_TIMEOUT);
}
}
else
{
//Close the event before we return
WSACloseEvent(hConnectedEvent);
//Throw the exception that the connect call failed unexpectedly
AfxThrowWSocketException(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
AfxThrowWSocketException();
}
}
}
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((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((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 = ((LPIN_ADDR)lphost->h_addr)->s_addr;
else
AfxThrowWSocketException();
}
//Call the other version of Connect which does the actual work
Connect((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, (LPSTR) lpBuf, nBufLen, nFlags);
if (nReceived == SOCKET_ERROR)
AfxThrowWSocketException();
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, (LPSTR) lpBuf, nBufLen, nFlags, lpSockAddr, lpSockAddrLen);
if (nReceived == SOCKET_ERROR)
AfxThrowWSocketException();
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, (SOCKADDR*)&sockAddr, &nSockAddrLen, nFlags);
nSocketPort = ntohs(sockAddr.sin_port);
sSocketAddress = inet_ntoa(sockAddr.sin_addr);
return nResult;
}
void CWSocket::Send(const void* pBuffer, int nBufLen, int nFlags)
{
ASSERT(IsCreated()); //must have been created first
if (send(m_hSocket, (char*) pBuffer, nBufLen, nFlags) == SOCKET_ERROR)
AfxThrowWSocketException();
}
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, (LPSTR) lpBuf, nBufLen, nFlags, lpSockAddr, nSockAddrLen);
if (nSent == SOCKET_ERROR)
AfxThrowWSocketException();
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((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 = ((LPIN_ADDR)lphost->h_addr)->s_addr;
else
AfxThrowWSocketException();
}
}
return SendTo(lpBuf, nBufLen, (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)
AfxThrowWSocketException();
}
void CWSocket::Listen(int nConnectionBacklog)
{
//Validate our parameters
ASSERT(IsCreated()); //must have been created first
if (listen(m_hSocket, nConnectionBacklog) == SOCKET_ERROR)
AfxThrowWSocketException();
}
void CWSocket::ShutDown(int nHow)
{
//Validate our parameters
ASSERT(IsCreated()); //must have been created first
if (shutdown(m_hSocket, nHow) == SOCKET_ERROR)
AfxThrowWSocketException();
}
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)
AfxThrowWSocketException();
}
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((u_short) nHostPort);
//Determine if the address is in dotted notation
LPSTR lpszAscii = T2A((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 = ((LPIN_ADDR)lphost->h_addr)->s_addr;
else
AfxThrowWSocketException();
}
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(((BYTE*) &reply) + nDataReceived, sizeof(reply) - nDataReceived);
nDataReceived += nData;
}
else
AfxThrowWSocketException(WSAETIMEDOUT);
}
//Validate the response
if ((reply.VN != 0) || (reply.CD != 90))
AfxThrowWSocketException(ERROR_BAD_NET_RESP);
}
catch(CWSocketException* pEx)
{
//Close the socket before we rethrow the exception
int nError = pEx->m_nError;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -