📄 tcpip.cpp
字号:
// or the socket is not created with the overlapped flag.
case WSAEINVAL :
// The virtual circuit was terminated
// due to a time-out or other failure.
case WSAECONNABORTED :
// The overlapped operation has been canceled due
// to the closure of the socket, or the execution
// of the SIO_FLUSH command in WSAIoctl.
case WSA_OPERATION_ABORTED :
// The virtual circuit was reset by the remote side.
case WSAECONNRESET:
sprintf(szMsg, "Server: Connection was reset by peer for Socket Address %d", this->m_Socket);
DisplayMessage(szMsg);
// this->CloseConnection(ClientSocket);
break;
// A blocking Windows Sockets call is in progress,
// or the service provider is still processing a callback function.
case WSAEINPROGRESS :
// Overlapped sockets:
// There are too many outstanding overlapped I/O requests.
// Nonoverlapped sockets:
// The socket is marked as nonblocking and the send operation
// cannot be completed immediately.
case WSAEWOULDBLOCK :
// The socket is message oriented, and the message
// is larger than the maximum supported by the
// underlying transport.
case WSAEMSGSIZE :
// No buffer space is available.
case WSAENOBUFS :
// An overlapped operation was successfully initiated and
// completion will be indicated at a later time.
case WSA_IO_PENDING :
// default. return value unknown.
// just go on.
default:
TRACE("TCP: Send attempt failed with error: %d\n",nError);
break;
}
dwBytesLeftToSend = 0;
dwErrorCode = IO_SEND_ERROR;
}
return(dwErrorCode);
}
//
// @mfunc Receive - In Tcp/Udp Client Mode
// This function receives request or data from a connected server
//
// @parm OUT unsigned char * | pBuf | Buffer to receive data
//
// @parm IN DWORD | dwSize | Maximum number of bytes to receive
//
// @parm OUT DWORD | dwSize | Actual number of bytes received
//
// @rvalue IO_SUCCESS | If successful
//
// @rvalue IO_RCV_PENDING | If receive still pending
//
// @rvalue IO_READPORT_ERROR | If receive failed
//
// @rvalue IO_CLIENT_ERR | If object not in client mode
//
EXPORT32 DWORD CTcpIp::Receive(OUT unsigned char *pBuf, IN DWORD dwSize,
OUT DWORD *dwActualSize)
{
int nError;
WSABUF sNetBuffer;
DWORD dwNumberOfBytesRecvd,
dwFlags = 0,
dwErrorCode = IO_SUCCESS;
TCHAR szMsg[256];
// This is a client not server. Just go away.
if (!this->m_bClient)
{
dwErrorCode = IO_CLIENT_ERR;
return(dwErrorCode);
}
if (DRV_CONNECTED == this->m_dwConnectState)
{
sNetBuffer.len = dwSize;
sNetBuffer.buf = (char *)pBuf;
if (this->m_bTcp)
{
// If this is a TCP
nError = WSARecv(this->m_Socket,
(LPWSABUF)&sNetBuffer,
1,
&dwNumberOfBytesRecvd,
&dwFlags,
&m_ReadOverlapped,
this->m_lpfnRcvCallback);
}
else
{
// If this is a UDP
nError = WSARecvFrom(this->m_Socket,
(LPWSABUF)&sNetBuffer,
1,
&dwNumberOfBytesRecvd,
&dwFlags,
(LPSOCKADDR)&m_sRemoteAddress,
&m_nRemoteAddressSize,
&m_ReadOverlapped,
this->m_lpfnRcvCallback);
}
if (ERROR_SUCCESS == nError)
{
*dwActualSize = dwNumberOfBytesRecvd;
}
else if (nError == SOCKET_ERROR)
{
nError = WSAGetLastError();
switch (nError)
{
// A successful WSAStartup must occour
case WSANOTINITIALISED :
sprintf(szMsg, "Receive Error %ud Successful startup not occoured for Ip Address %s", nError, this->m_szIpAddress);
DisplayMessage(szMsg);
dwErrorCode = IO_READPORT_ERROR;
*dwActualSize = 0;
this->Close();
this->Open();
break;
// The network subsystem has failed
case WSAENETDOWN :
sprintf(szMsg, "Receive Error %ud Network Sub-system failed for Ip Address %s", nError, this->m_szIpAddress);
DisplayMessage(szMsg);
dwErrorCode = IO_READPORT_ERROR;
*dwActualSize = 0;
this->Close();
this->Open();
break;
// The requested address is a broadcast address,
// but the appropriate flag was not set.
case WSAEACCES :
sprintf(szMsg, "Receive Error %ud Requested address flag incorrect for Ip Address %s", nError, this->m_szIpAddress);
DisplayMessage(szMsg);
dwErrorCode = IO_READPORT_ERROR;
*dwActualSize = 0;
this->Close();
this->Open();
break;
// A blocking Windows Sockets call was canceled through
// WSACancelBlockingCall
case WSAEINTR :
sprintf(szMsg, "Receive Error %ud Socket call cancelled for Ip Address %s", nError, this->m_szIpAddress);
DisplayMessage(szMsg);
dwErrorCode = IO_READPORT_ERROR;
*dwActualSize = 0;
this->Close();
this->Open();
break;
// The lpBuffers, lpNumberOfBytesSent, lpOverlapped,
// lpCompletionRoutine argument is not totally contained
// in a valid part of the user address space.
//
case WSAEFAULT :
sprintf(szMsg, "Receive Error %ud Arguement not valid part of user address space for Ip Address %s", nError, this->m_szIpAddress);
DisplayMessage(szMsg);
dwErrorCode = IO_READPORT_ERROR;
*dwActualSize = 0;
this->Close();
this->Open();
break;
// The connection has been broken due to "keep-alive" activity
// detecting a failure while the operation was in progress.
case WSAENETRESET :
sprintf(szMsg, "Receive Error %ud Connection was broken due to failure in operation for Ip Address %s", nError, this->m_szIpAddress);
DisplayMessage(szMsg);
dwErrorCode = IO_READPORT_ERROR;
*dwActualSize = 0;
this->Close();
this->Open();
break;
// The socket is not connected.
case WSAENOTCONN :
sprintf(szMsg, "Receive Error %ud Socket not connected for Ip Address %s", nError, this->m_szIpAddress);
DisplayMessage(szMsg);
dwErrorCode = IO_READPORT_ERROR;
*dwActualSize = 0;
this->Close();
this->Open();
break;
// The descriptor is not a socket.
case WSAENOTSOCK :
sprintf(szMsg, "Receive Error %ud Descriptor not a socket for Ip Address %s", nError, this->m_szIpAddress);
DisplayMessage(szMsg);
dwErrorCode = IO_READPORT_ERROR;
*dwActualSize = 0;
this->Close();
this->Open();
break;
// The referenced socket is not a type that supports
// connection-oriented service.
case WSAEOPNOTSUPP :
sprintf(szMsg, "Receive Error %ud Socket incorrect type for Ip Address %s", nError, this->m_szIpAddress);
DisplayMessage(szMsg);
dwErrorCode = IO_READPORT_ERROR;
*dwActualSize = 0;
this->Close();
this->Open();
break;
// The socket has been shut down; it is not possible
// to WSASend on a socket after shutdown has been invoked
// with how set to SD_SEND or SD_BOTH.
case WSAESHUTDOWN :
sprintf(szMsg, "Receive Error %ud Socket has been shut down for Ip Address %s", nError, this->m_szIpAddress);
DisplayMessage(szMsg);
dwErrorCode = IO_READPORT_ERROR;
*dwActualSize = 0;
this->Close();
this->Open();
break;
// The socket has not been bound with bind,
// or the socket is not created with the overlapped flag.
case WSAEINVAL :
sprintf(szMsg, "Receive Error %ud Socket has not been bound for Ip Address %s", nError, this->m_szIpAddress);
DisplayMessage(szMsg);
dwErrorCode = IO_READPORT_ERROR;
*dwActualSize = 0;
this->Close();
this->Open();
break;
// The virtual circuit was terminated
// due to a time-out or other failure.
case WSAECONNABORTED :
sprintf(szMsg, "Receive Error %ud Connection was terminated for Ip Address %s", nError, this->m_szIpAddress);
DisplayMessage(szMsg);
dwErrorCode = IO_READPORT_ERROR;
*dwActualSize = 0;
this->Close();
this->Open();
break;
// The overlapped operation has been canceled due
// to the closure of the socket, or the execution
// of the SIO_FLUSH command in WSAIoctl.
case WSA_OPERATION_ABORTED :
sprintf(szMsg, "Receive Error %ud Operation has been aborted for Ip Address %s", nError, this->m_szIpAddress);
DisplayMessage(szMsg);
dwErrorCode = IO_READPORT_ERROR;
*dwActualSize = 0;
this->Close();
this->Open();
break;
// The virtual circuit was reset by the remote side.
case WSAECONNRESET:
sprintf(szMsg, "Receive Error %ud Connection was reset by peer for Ip Address %s", nError, this->m_szIpAddress);
DisplayMessage(szMsg);
dwErrorCode = IO_READPORT_ERROR;
*dwActualSize = 0;
this->Close();
this->Open();
break;
// A blocking Windows Sockets call is in progress,
// or the service provider is still processing a callback function.
case WSAEINPROGRESS :
sprintf(szMsg, "Recv still in progress for Ip Address %s", this->m_szIpAddress);
// DisplayMessage(szMsg);
*dwActualSize = dwNumberOfBytesRecvd;
dwErrorCode = IO_RCV_PENDING;
break;
// Overlapped sockets:
// There are too many outstanding overlapped I/O requests.
// Nonoverlapped sockets:
// The socket is marked as nonblocking and the send operation
// cannot be completed immediately.
case WSAEWOULDBLOCK :
sprintf(szMsg, "Recv Would Block for Ip Address %s", this->m_szIpAddress);
// DisplayMessage(szMsg);
*dwActualSize = dwNumberOfBytesRecvd;
dwErrorCode = IO_RCV_PENDING;
break;
// The socket is message oriented, and the message
// is larger than the maximum supported by the
// underlying transport.
case WSAEMSGSIZE :
sprintf(szMsg, "Recv Message larger than that supported for Ip Address %s", this->m_szIpAddress);
DisplayMessage(szMsg);
*dwActualSize = dwNumberOfBytesRecvd;
dwErrorCode = IO_RCV_PENDING;
break;
// No buffer space is available.
case WSAENOBUFS :
sprintf(szMsg, "Recv Message No Buffer space for Ip Address %s", this->m_szIpAddress);
DisplayMessage(szMsg);
*dwActualSize = dwNumberOfBytesRecvd;
dwErrorCode = IO_RCV_PENDING;
break;
// An overlapped operation was successfully initiated and
// completion will be indicated at a later time.
case WSA_IO_PENDING :
sprintf(szMsg, "Recv Message I/O still pending for Ip Address %s", this->m_szIpAddress);
// DisplayMessage(szMsg);
*dwActualSize = dwNumberOfBytesRecvd;
dwErrorCode = IO_RCV_PENDING;
break;
// default. return value unknown.
// just go on.
default:
sprintf(szMsg, "Recv Message error unknown for Ip Address %s", this->m_szIpAddress);
// DisplayMessage(szMsg);
TRACE("TCP: Send attempt failed with error: %d\n", nError);
*dwActualSize = dwNumberOfBytesRecvd;
dwErrorCode = IO_RCV_PENDING;
break;
}
}// End else -if loop
else
{
sprintf(szMsg, "Error Recv %ud Unknown for Ip Address %s", nError, this->m_szIpAddress);
DisplayMessage(szMsg);
dwErrorCode = IO_READPORT_ERROR;
*dwActualSize = 0;
this->Close();
this->Open();
}
}
else
{
sprintf(szMsg, "Tried to RECEIVE but connection not established for Ip Address %s", this->m_szIpAddress);
DisplayMessage(szMsg);
dwErrorCode = IO_READPORT_ERROR;
*dwActualSize = 0;
}
return(dwErrorCode);
}
//
// @mfunc SetSocketBufferOptions - In Tcp/Udp Client Mode
// This function sets the Send and Receive Socket Buffer options
//
// @parm IN const TCHAR * | szRxBufSize | Receive Buffer Size in bytes
//
// @parm IN int | nRxBufSizeLen | Sizeof szRxBufSize
//
// @parm IN const TCHAR * | szTxBufSize | Transmit Buffer Size in bytes
//
// @parm IN int | nTxBufSizeLen | Sizeof szTxBufSize
//
// @parm OUT int * | dpLastError | Last Error Number
//
// @rvalue IO_SUCCESS | If successful
//
// @rvalue IO_SOCKET_OPTION_ERROR | If fails
//
// @rvalue IO_CLIENT_ERR | If object not in client mode
//
// @rvalue IO_SOCKET_ERROR | If Client Socket Invalid
//
EXPORT32 DWORD CTcpIp::SetSocketBufferOptions (IN const TCHAR *szRxBufSize, IN int nRxBufSizeLen,
IN const TCHAR *szTxBufSize, IN int nTxBufSizeLen,
OUT int *dpLastError)
{
DWORD dwErrorCode = IO_SUCCESS;
int nError;
// This is a client not server. Just go away.
if (!this->m_bClient)
{
dwErrorCode = IO_CLIENT_ERR;
return(dwErrorCode);
}
//
// If Socket not created or already closed; then just return
// If you add any other states then you may want to change this.
//
if (this->m_bSocketState != SOCKET_CREATED)
{
dwErrorCode = IO_SOCKET_ERROR;
return(dwErrorCode);
}
//
// Set socket options on this socket
//
if ( ((nError = setsockopt(this->m_Socket, SOL_SOCKET, SO_RCVBUF, (char *)szRxBufSize, nRxBufSizeLen)) == SOCKET_ERROR) ||
((nError = setsockopt(this->m_Socket, SOL_SOCKET, SO_SNDBUF, (char *)szTxBufSize, nTxBufSizeLen)) == SOCKET_ERROR) )
{
//
// Unable to set the socket options
//
*dpLastError = WSAGetLastError();
dwErrorCode = IO_SOCKET_OPTION_ERROR;
}
return(dwErrorCode);
}
//
// @mfunc GetSocketBufferOptions - In Tcp/Udp Client Mode
// This function gets the common socket Buffer options
//
// @parm OUT TCHAR * | szSOSendBuf | Send Buffer Size in bytes
//
// @parm IN OUT int * | dpSOSendBufSize | Sizeof szSOSendBuf
//
// @parm OUT TCHAR * | szSORcvBuf | Receive Buffer Size in bytes
//
// @parm IN OUT int * | dpSORcvBufSize | Sizeof szSORcvBuf
//
// @parm OUT int * | dpLastError | Last Error Number
//
// @rvalue IO_SUCCESS | If successful
//
// @rvalue IO_SOCKET_OPTION_ERROR | If fails
//
// @rvalue IO_CLIENT_ERR | If object not in client mode
//
// @rvalue IO_SOCKET_ERROR | If Client Socket Invalid
//
EXPORT32 DWORD CTcpIp::GetSocketBufferOptions (OUT TCHAR *szSOSendBuf, IN OUT int *dpSOSendBufSize,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -