blocksock.cpp
资源名称:FTP服务器源代码.zip [点击查看]
上传用户:shengde
上传日期:2007-02-26
资源大小:117k
文件大小:9k
源码类别:
Ftp服务器
开发平台:
Visual C++
- #include "stdafx.h"
- #include "blocksock.h"
- IMPLEMENT_DYNAMIC(CBlockingSocketException, CException)
- CBlockingSocketException::CBlockingSocketException(char* pchMessage)
- {
- m_strMessage = pchMessage;
- m_nError = WSAGetLastError();
- }
- BOOL CBlockingSocketException::GetErrorMessage(LPTSTR lpstrError, UINT nMaxError,
- PUINT pnHelpContext /*= NULL*/)
- {
- char text[200];
- if(m_nError == 0) {
- wsprintf(text, "%s error", (const char*) m_strMessage);
- }
- else {
- wsprintf(text, "%s error #%d", (const char*) m_strMessage, m_nError);
- }
- strncpy(lpstrError, text, nMaxError - 1);
- return TRUE;
- }
- IMPLEMENT_DYNAMIC(CBlockingSocket, CObject)
- void CBlockingSocket::Cleanup()
- {
- // doesn't throw an exception because it's called in a catch block
- if(m_hSocket == NULL) return;
- VERIFY(closesocket(m_hSocket) != SOCKET_ERROR);
- m_hSocket = NULL;
- }
- bool CBlockingSocket::Create(int nType /* = SOCK_STREAM */)
- {
- ASSERT(m_hSocket == NULL);
- if((m_hSocket = socket(AF_INET, nType, 0)) == INVALID_SOCKET)
- return false;
- else
- return true;
- }
- bool CBlockingSocket::Bind(LPCSOCKADDR psa)
- {
- ASSERT(m_hSocket != NULL);
- if(bind(m_hSocket, psa, sizeof(SOCKADDR)) == SOCKET_ERROR)
- return false;
- else
- return true;
- }
- bool CBlockingSocket::Listen()
- {
- ASSERT(m_hSocket != NULL);
- if(listen(m_hSocket, 5) == SOCKET_ERROR)
- return false;
- else
- return true;
- }
- BOOL CBlockingSocket::Accept(CBlockingSocket& sConnect, LPSOCKADDR psa)
- {
- ASSERT(m_hSocket != NULL);
- ASSERT(sConnect.m_hSocket == NULL);
- int nLengthAddr = sizeof(SOCKADDR);
- sConnect.m_hSocket = accept(m_hSocket, psa, &nLengthAddr);
- if(sConnect == INVALID_SOCKET) {
- // no exception if the listen was canceled
- if(WSAGetLastError() != WSAEINTR) {
- throw new CBlockingSocketException("Accept");
- }
- return FALSE;
- }
- return TRUE;
- }
- void CBlockingSocket::Close()
- {
- if (NULL == m_hSocket)
- return;
- if(closesocket(m_hSocket) == SOCKET_ERROR) {
- // should be OK to close if closed already
- throw new CBlockingSocketException("Close");
- }
- m_hSocket = NULL;
- }
- bool CBlockingSocket::Connect(LPCSOCKADDR psa)
- {
- ASSERT(m_hSocket != NULL);
- // should timeout by itself
- if(connect(m_hSocket, psa, sizeof(SOCKADDR)) == SOCKET_ERROR)
- return false;
- else
- return true;
- }
- int CBlockingSocket::Write(const char* pch, const int nSize, const int nSecs)
- {
- int nBytesSent = 0;
- int nBytesThisTime;
- const char* pch1 = pch;
- do {
- nBytesThisTime = Send(pch1, nSize - nBytesSent, nSecs);
- nBytesSent += nBytesThisTime;
- pch1 += nBytesThisTime;
- } while(nBytesSent < nSize);
- return nBytesSent;
- }
- int CBlockingSocket::Send(const char* pch, const int nSize, const int nSecs)
- {
- ASSERT(m_hSocket != NULL);
- // returned value will be less than nSize if client cancels the reading
- FD_SET fd = {1, m_hSocket};
- TIMEVAL tv = {nSecs, 0};
- if(select(0, NULL, &fd, NULL, &tv) == 0) {
- throw new CBlockingSocketException("Send timeout");
- }
- int nBytesSent;
- if((nBytesSent = send(m_hSocket, pch, nSize, 0)) == SOCKET_ERROR) {
- throw new CBlockingSocketException("Send");
- }
- return nBytesSent;
- }
- int CBlockingSocket::Receive(char* pch, const int nSize, const int nSecs)
- {
- ASSERT(m_hSocket != NULL);
- FD_SET fd = {1, m_hSocket};
- TIMEVAL tv = {nSecs, 0};
- if(select(0, &fd, NULL, NULL, &tv) == 0) {
- throw new CBlockingSocketException("Receive timeout");
- }
- int nBytesReceived;
- if((nBytesReceived = recv(m_hSocket, pch, nSize, 0)) == SOCKET_ERROR) {
- throw new CBlockingSocketException("Receive");
- }
- return nBytesReceived;
- }
- int CBlockingSocket::ReceiveDatagram(char* pch, const int nSize, LPSOCKADDR psa, const int nSecs)
- {
- ASSERT(m_hSocket != NULL);
- FD_SET fd = {1, m_hSocket};
- TIMEVAL tv = {nSecs, 0};
- if(select(0, &fd, NULL, NULL, &tv) == 0) {
- throw new CBlockingSocketException("Receive timeout");
- }
- // input buffer should be big enough for the entire datagram
- int nFromSize = sizeof(SOCKADDR);
- int nBytesReceived = recvfrom(m_hSocket, pch, nSize, 0, psa, &nFromSize);
- if(nBytesReceived == SOCKET_ERROR) {
- throw new CBlockingSocketException("ReceiveDatagram");
- }
- return nBytesReceived;
- }
- int CBlockingSocket::SendDatagram(const char* pch, const int nSize, LPCSOCKADDR psa, const int nSecs)
- {
- ASSERT(m_hSocket != NULL);
- FD_SET fd = {1, m_hSocket};
- TIMEVAL tv = {nSecs, 0};
- if(select(0, NULL, &fd, NULL, &tv) == 0) {
- throw new CBlockingSocketException("Send timeout");
- }
- int nBytesSent = sendto(m_hSocket, pch, nSize, 0, psa, sizeof(SOCKADDR));
- if(nBytesSent == SOCKET_ERROR) {
- throw new CBlockingSocketException("SendDatagram");
- }
- return nBytesSent;
- }
- void CBlockingSocket::GetPeerAddr(LPSOCKADDR psa)
- {
- ASSERT(m_hSocket != NULL);
- // gets the address of the socket at the other end
- int nLengthAddr = sizeof(SOCKADDR);
- if(getpeername(m_hSocket, psa, &nLengthAddr) == SOCKET_ERROR) {
- throw new CBlockingSocketException("GetPeerName");
- }
- }
- void CBlockingSocket::GetSockAddr(LPSOCKADDR psa)
- {
- ASSERT(m_hSocket != NULL);
- // gets the address of the socket at this end
- int nLengthAddr = sizeof(SOCKADDR);
- if(getsockname(m_hSocket, psa, &nLengthAddr) == SOCKET_ERROR) {
- throw new CBlockingSocketException("GetSockName");
- }
- }
- //static
- CSockAddr CBlockingSocket::GetHostByName(const char* pchName, const USHORT ushPort /* = 0 */)
- {
- hostent* pHostEnt = gethostbyname(pchName);
- if(pHostEnt == NULL) {
- throw new CBlockingSocketException("GetHostByName");
- }
- ULONG* pulAddr = (ULONG*) pHostEnt->h_addr_list[0];
- SOCKADDR_IN sockTemp;
- sockTemp.sin_family = AF_INET;
- sockTemp.sin_port = htons(ushPort);
- sockTemp.sin_addr.s_addr = *pulAddr; // address is already in network byte order
- return sockTemp;
- }
- //static
- const char* CBlockingSocket::GetHostByAddr(LPCSOCKADDR psa)
- {
- hostent* pHostEnt = gethostbyaddr((char*) &((LPSOCKADDR_IN) psa)
- ->sin_addr.s_addr, 4, PF_INET);
- if(pHostEnt == NULL) {
- throw new CBlockingSocketException("GetHostByAddr");
- }
- return pHostEnt->h_name; // caller shouldn't delete this memory
- }
- // Class CHttpBlockingSocket
- IMPLEMENT_DYNAMIC(CHttpBlockingSocket, CBlockingSocket)
- CHttpBlockingSocket::CHttpBlockingSocket()
- {
- m_pReadBuf = new char[nSizeRecv];
- m_nReadBuf = 0;
- }
- CHttpBlockingSocket::~CHttpBlockingSocket()
- {
- delete [] m_pReadBuf;
- }
- int CHttpBlockingSocket::ReadHttpHeaderLine(char* pch, const int nSize, const int nSecs)
- // reads an entire header line through CRLF (or socket close)
- // inserts zero string terminator, object maintains a buffer
- {
- int nBytesThisTime = m_nReadBuf;
- int nLineLength = 0;
- char* pch1 = m_pReadBuf;
- char* pch2;
- do {
- // look for lf (assume preceded by cr)
- if((pch2 = (char*) memchr(pch1 , 'n', nBytesThisTime)) != NULL) {
- ASSERT((pch2) > m_pReadBuf);
- ASSERT(*(pch2 - 1) == 'r');
- nLineLength = (pch2 - m_pReadBuf) + 1;
- if(nLineLength >= nSize) nLineLength = nSize - 1;
- memcpy(pch, m_pReadBuf, nLineLength); // copy the line to caller
- m_nReadBuf -= nLineLength;
- memmove(m_pReadBuf, pch2 + 1, m_nReadBuf); // shift remaining characters left
- break;
- }
- pch1 += nBytesThisTime;
- nBytesThisTime = Receive(m_pReadBuf + m_nReadBuf, nSizeRecv - m_nReadBuf, nSecs);
- if(nBytesThisTime <= 0) { // sender closed socket or line longer than buffer
- throw new CBlockingSocketException("ReadHeaderLine");
- }
- m_nReadBuf += nBytesThisTime;
- }
- while(TRUE);
- *(pch + nLineLength) = ' ';
- return nLineLength;
- }
- int CHttpBlockingSocket::ReadHttpResponse(char* pch, const int nSize, const int nSecs)
- // reads remainder of a transmission through buffer full or socket close
- // (assume headers have been read already)
- {
- int nBytesToRead, nBytesThisTime, nBytesRead = 0;
- if(m_nReadBuf > 0) { // copy anything already in the recv buffer
- memcpy(pch, m_pReadBuf, m_nReadBuf);
- pch += m_nReadBuf;
- nBytesRead = m_nReadBuf;
- m_nReadBuf = 0;
- }
- do { // now pass the rest of the data directly to the caller
- nBytesToRead = min(nSizeRecv, nSize - nBytesRead);
- nBytesThisTime = Receive(pch, nBytesToRead, nSecs);
- if(nBytesThisTime <= 0) break; // sender closed the socket
- pch += nBytesThisTime;
- nBytesRead += nBytesThisTime;
- }
- while(nBytesRead <= nSize);
- return nBytesRead;
- }
- void LogBlockingSocketException(LPVOID pParam, char* pch, CBlockingSocketException* pe)
- { // pParam holds the HWND for the destination window (in another thread)
- CString strGmt = CTime::GetCurrentTime().FormatGmt("%m/%d/%y %H:%M:%S GMT");
- char text1[200], text2[50];
- pe->GetErrorMessage(text2, 49);
- wsprintf(text1, "WINSOCK ERROR--%s %s -- %srn", pch, text2, (const char*) strGmt);
- ::SendMessage((HWND) pParam, EM_SETSEL, (WPARAM) 65534, 65535);
- ::SendMessage((HWND) pParam, EM_REPLACESEL, (WPARAM) 0, (LPARAM) text1);
- }