📄 subject_19511.htm
字号:
<blockquote><p>
回复者:中国娃娃 回复日期:2002-10-29 17:09:33
<br>内容:最好把你这个CBlockSocket的声明和定义贴出来。
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:hf 回复日期:2002-10-29 17:13:12
<br>内容:// blocksock.h<BR><BR>#define SECONDS_MIN 1 // min seconds of timeout<BR>#define SECONDS_MAX 10 // max seconds of timeout<BR>#define SECONDS_DEF 10 // min seconds of timeout<BR><BR>typedef const struct sockaddr* LPCSOCKADDR;<BR><BR>// Class CBlockSocketExcption<BR>class CBlockSocketException : public CException<BR>{<BR> DECLARE_DYNAMIC(CBlockSocketException)<BR>public:<BR> CBlockSocketException(char* pchMessage);<BR> ~CBlockSocketException(){}<BR>private:<BR> int m_nError;<BR> CString m_strMessage;<BR>};<BR><BR>// Class CSockAddr<BR>class CSockAddr : public sockaddr_in <BR>{<BR>public:<BR> // 缺省构造函数<BR> CSockAddr() <BR> { <BR> sin_family = AF_INET;<BR> sin_port = 0;<BR> sin_addr.s_addr = 0;<BR> }<BR> // 拷贝构造函数<BR> CSockAddr(const SOCKADDR& sa) <BR> {<BR> memcpy(this, &sa, sizeof(SOCKADDR)); <BR> }<BR> // 拷贝构造函数<BR> CSockAddr(const SOCKADDR_IN& sin) <BR> {<BR> memcpy(this, &sin, sizeof(SOCKADDR_IN));<BR> }<BR> // 构造函数,主机字节顺序<BR> CSockAddr(const ULONG ulAddr, const USHORT ushPort = 0) <BR> {<BR> sin_family = AF_INET;<BR> sin_port = htons(ushPort);<BR> sin_addr.s_addr = htonl(ulAddr);<BR> }<BR> // 构造函数,主机字节顺序,ip地址是点分十进制格式<BR> CSockAddr(const char* pchIP, const USHORT ushPort = 0) <BR> {<BR> sin_family = AF_INET;<BR> sin_port = htons(ushPort);<BR> sin_addr.s_addr = inet_addr(pchIP);<BR> }<BR> // 取点分十进制格式的ip地址<BR> char* DottedDecimal() <BR> {<BR> return(inet_ntoa(sin_addr));<BR> }<BR> // 取端口号<BR> USHORT Port() const <BR> {<BR> return(ntohs(sin_port));<BR> }<BR> // 取ip地址<BR> ULONG IPAddr() const <BR> {<BR> return(ntohl(sin_addr.s_addr));<BR> }<BR> // 重载运算符=<BR> const CSockAddr& operator=(const SOCKADDR& sa) <BR> {<BR> memcpy(this, &sa, sizeof(SOCKADDR));<BR> return *this;<BR> }<BR> // 重载运算符=<BR> const CSockAddr& operator=(const SOCKADDR_IN& sin) <BR> {<BR> memcpy(this, &sin, sizeof(SOCKADDR_IN));<BR> return *this;<BR> }<BR> // 运算符SOCKADDR<BR> operator SOCKADDR() <BR> {<BR> return *((LPSOCKADDR) this);<BR> }<BR> // 运算符LPSOCKADDR<BR> operator LPSOCKADDR() <BR> {<BR> return (LPSOCKADDR) this;<BR> }<BR> // 运算符LPSOCKADDR_IN<BR> operator LPSOCKADDR_IN() <BR> {<BR> return (LPSOCKADDR_IN) this;<BR> }<BR>};<BR><BR>// Class CBlockSocket<BR>class CBlockSocket : public CObject <BR>{<BR> DECLARE_DYNAMIC(CBlockSocket)<BR>public:<BR> //成员变量<BR> SOCKET m_hSocket;<BR> <BR> // 缺省构造函数,创建一个没有初始化的对象<BR> CBlockSocket::CBlockSocket()<BR> {<BR> m_hSocket = NULL;<BR> }<BR><BR> // 缺省析构函数<BR> CBlockSocket::~CBlockSocket(){ }<BR><BR> // 调用Winsock的socket函数,然后把m_hSocket设置为返回的32位SOCKET句柄<BR> void Create(int nType = SOCK_STREAM);<BR><BR> // 调用Winsock的closesocket函数,关闭一个已打开的SOCKET<BR> void Close();<BR><BR> // 如果SOCKET是打开的话,该函数关闭SOCKET,它不会陷入异常,可以在异常处理中调用该函数<BR> void Cleanup();<BR><BR> void Bind(LPCSOCKADDR psa);<BR> <BR> void Listen();<BR> <BR> void Connect(LPCSOCKADDR psa);<BR> <BR> BOOL Accept(CBlockSocket& sConnect, LPSOCKADDR psa);<BR> <BR> // 该TCP函数调用Winsock的select函数以激活超时处理之后,再调用Winsock的send函数<BR> // 每个Send调用实际传送的字节数依赖于连接另一端接收程序接收字节的速度<BR> // 如果另一端的接收程序在读完数据之前关闭SOCKET,Send将陷入异常<BR> int Send(const char* pch, const int nSize, int nSeconds = SECONDS_DEF);<BR><BR> // 该TCP函数调用Winsock的select函数以激活超时处理之后,再调用Winsock的recv函数<BR> int Receive(char* pch, const int nSize, int nSeconds = SECONDS_DEF);<BR><BR> // 该TCP函数连续调用Send函数,直到所有的字节都被发送出去或者接收端关闭SOCKET<BR> int Write(const char* pch, const int nSize, int nSeconds = SECONDS_DEF);<BR> <BR> // 该TCP函数连续调用Receive函数,直到所有的字节都被接收到或者发送端关闭SOCKET<BR> int Read(char* pch, const int nSize, int nSeconds = SECONDS_DEF);<BR> <BR> int SendDatagram(const char* pch, const int nSize, LPCSOCKADDR psa, int nSeconds = SECONDS_DEF);<BR> <BR> int ReceiveDatagram(char *pch, const int nSize, LPSOCKADDR psa, int nSeconds = SECONDS_DEF);<BR> <BR> // 得到连接另一端的SOCKET地址<BR> void GetPeerAddr(LPSOCKADDR psa);<BR> <BR> // 得到连接这一端的SOCKET地址<BR> void GetSockAddr(LPSOCKADDR psa);<BR> <BR> static CSockAddr GetHostByName(const char* pchName, const USHORT ushPort);<BR><BR> static const char* GetHostByAddr(LPCSOCKADDR psa);<BR> <BR> operator SOCKET() <BR> {<BR> return m_hSocket;<BR> }<BR>};<BR><BR><BR>#include <stdafx.h><BR>#include "BlockSocket.h"<BR><BR>//class CBlockSocketException<BR>IMPLEMENT_DYNAMIC(CBlockSocketException, CException)<BR><BR>CBlockSocketException::CBlockSocketException(char* pchMessage)<BR>{<BR> m_strMessage = pchMessage;<BR>}<BR><BR>//class CBlockSocket<BR>IMPLEMENT_DYNAMIC(CBlockSocket, CObject)<BR><BR>void CBlockSocket::Cleanup()<BR>{<BR> if (m_hSocket == NULL) return;<BR> VERIFY(closesocket(m_hSocket) != SOCKET_ERROR);<BR> m_hSocket = NULL;<BR>}<BR><BR>void CBlockSocket::Create(int nType)<BR>{<BR> ASSERT(m_hSocket == NULL);<BR> if ((m_hSocket = socket(AF_INET, nType, 0)) == INVALID_SOCKET)<BR> {<BR> throw new CBlockSocketException("Create");<BR> }<BR>}<BR><BR>void CBlockSocket::Bind(LPCSOCKADDR psa)<BR>{<BR> ASSERT(m_hSocket != NULL);<BR> int nReuseaddr = 1;<BR> int nIntSize = sizeof(int);<BR> setsockopt(m_hSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&nReuseaddr, nIntSize);<BR> if (bind(m_hSocket, psa, sizeof(SOCKADDR)) == SOCKET_ERROR)<BR> {<BR> throw new CBlockSocketException("Bind");<BR> }<BR>}<BR><BR>void CBlockSocket::Listen()<BR>{<BR> ASSERT(m_hSocket != NULL);<BR> if (listen(m_hSocket, 5) == SOCKET_ERROR)<BR> {<BR> throw new CBlockSocketException("Listen");<BR> }<BR>}<BR><BR>BOOL CBlockSocket::Accept(CBlockSocket& sConnect, LPSOCKADDR psa)<BR>{<BR> ASSERT(m_hSocket != NULL);<BR> ASSERT(sConnect.m_hSocket == NULL);<BR> int nLengthAddr = sizeof(SOCKADDR);<BR> sConnect.m_hSocket = accept(m_hSocket, psa, &nLengthAddr);<BR> if (sConnect == INVALID_SOCKET)<BR> {<BR> if (WSAGetLastError() != WSAEINTR)<BR> {<BR> throw new CBlockSocketException("Accept");<BR> }<BR> return FALSE;<BR> }<BR> return TRUE;<BR>}<BR><BR>void CBlockSocket::Close()<BR>{<BR> ASSERT(m_hSocket != NULL);<BR> if (closesocket(m_hSocket) == SOCKET_ERROR)<BR> {<BR> throw new CBlockSocketException("Close");<BR> }<BR> m_hSocket = NULL;<BR>}<BR><BR>void CBlockSocket::Connect(LPCSOCKADDR psa)<BR>{<BR> ASSERT(m_hSocket != NULL);<BR> if (connect(m_hSocket, psa, sizeof(SOCKADDR)) == SOCKET_ERROR)<BR> {<BR> throw new CBlockSocketException("Connect");<BR> }<BR>}<BR><BR>int CBlockSocket::Send(const char* pch, const int nSize, int nSeconds)<BR>{<BR> ASSERT(m_hSocket != NULL);<BR> ASSERT(nSize > 0);<BR> if (nSeconds < SECONDS_MIN) nSeconds = SECONDS_MIN;<BR> if (nSeconds > SECONDS_MAX) nSeconds = SECONDS_MAX;<BR> FD_SET fd = {1, m_hSocket};<BR> TIMEVAL tv = {nSeconds, 0};<BR> if (select(0, NULL, &fd, NULL, &tv) == 0)<BR> {<BR> throw new CBlockSocketException("Send timeout");<BR> }<BR> int nBytesSent = send(m_hSocket, pch, nSize, 0);<BR> if (nBytesSent == SOCKET_ERROR)<BR> {<BR> throw new CBlockSocketException("Send");<BR> }<BR> return nBytesSent;<BR>}<BR><BR>int CBlockSocket::Receive(char* pch, const int nSize, int nSeconds)<BR>{<BR> ASSERT(m_hSocket != NULL);<BR> ASSERT(nSize > 0);<BR> if (nSeconds < SECONDS_MIN) nSeconds = SECONDS_MIN;<BR> if (nSeconds > SECONDS_MAX) nSeconds = SECONDS_MAX;<BR> FD_SET fd = {1, m_hSocket};<BR> TIMEVAL tv = {nSeconds, 0};<BR> if (select(0, &fd, NULL, NULL, &tv) == 0)<BR> {<BR> throw new CBlockSocketException("Receive timeout");<BR> }<BR> int nBytesReceived = recv(m_hSocket, pch, nSize, 0);<BR> if (nBytesReceived == SOCKET_ERROR)<BR> {<BR> throw new CBlockSocketException("Receive");<BR> }<BR> return nBytesReceived;<BR>}<BR><BR>int CBlockSocket::Write(const char* pch, const int nSize, int nSeconds)<BR>{<BR> ASSERT(nSize>0);<BR> int nBytesSent = 0;<BR> int nBytesThisTime;<BR> const char* pch1 = pch;<BR> do{<BR> nBytesThisTime = Send(pch1, nSize - nBytesSent, nSeconds);<BR> if(nBytesThisTime <= 0) break;<BR> nBytesSent += nBytesThisTime;<BR> pch1 += nBytesThisTime;<BR> }while(nBytesSent < nSize);<BR> return nBytesSent;<BR>}<BR><BR>int CBlockSocket::Read(char* pch, const int nSize, int nSeconds)<BR>{<BR> ASSERT(nSize>0);<BR> int nBytesRead = 0;<BR> int nBytesThisTime;<BR> char* pch1 = pch;<BR> do{<BR> nBytesThisTime = Receive(pch1, nSize - nBytesRead, nSeconds);<BR> if(nBytesThisTime <= 0) break;<BR> nBytesRead += nBytesThisTime;<BR> pch1 += nBytesThisTime;<BR> }while(nBytesRead < nSize);<BR> return nBytesRead;<BR>}<BR><BR>int CBlockSocket::SendDatagram(const char* pch, const int nSize, LPCSOCKADDR psa, int nSeconds)<BR>{<BR> ASSERT(m_hSocket != NULL);<BR> ASSERT(nSize>0);<BR> FD_SET fd = {1, m_hSocket};<BR> TIMEVAL tv = {nSeconds, 0};<BR> if (select(0, NULL, &fd, NULL, &tv) == 0)<BR> {<BR> throw new CBlockSocketException("Send timeout");<BR> }<BR><BR> int nBytesSent = sendto(m_hSocket, pch, nSize, 0, psa, sizeof(SOCKADDR));<BR> if (nBytesSent == SOCKET_ERROR)<BR> {<BR> throw new CBlockSocketException("SendDatagram");<BR> }<BR> return nBytesSent;<BR>}<BR><BR>int CBlockSocket::ReceiveDatagram(char *pch, const int nSize, LPSOCKADDR psa, int nSeconds)<BR>{<BR> ASSERT(m_hSocket != NULL);<BR> ASSERT(nSize>0);<BR> FD_SET fd = {1, m_hSocket};<BR> TIMEVAL tv = {nSeconds, 0};<BR> if (select(0, &fd, NULL, NULL, &tv) == 0)<BR> {<BR> throw new CBlockSocketException("Receive timeout");<BR> }<BR> int nFromSize = sizeof(SOCKADDR);<BR> int nBytesReceived = recvfrom(m_hSocket, pch, nSize, 0, psa, &nFromSize);<BR> if (nBytesReceived == SOCKET_ERROR)<BR> {<BR> throw new CBlockSocketException("ReceiveDatagram");<BR> }<BR> return nBytesReceived;<BR>}<BR><BR>void CBlockSocket::GetPeerAddr(LPSOCKADDR psa)<BR>{<BR> ASSERT(m_hSocket != NULL);<BR> int nLengthAddr = sizeof(SOCKADDR);<BR> if (getpeername(m_hSocket, psa, &nLengthAddr) == SOCKET_ERROR)<BR> {<BR> throw new CBlockSocketException("GetPeerAddr");<BR> }<BR>}<BR><BR>void CBlockSocket::GetSockAddr(LPSOCKADDR psa)<BR>{<BR> ASSERT(m_hSocket != NULL);<BR> int nLengthAddr = sizeof(SOCKADDR);<BR> if (getsockname(m_hSocket, psa, &nLengthAddr) == SOCKET_ERROR)<BR> {<BR> throw new CBlockSocketException("GetSockAddr");<BR> }<BR>}<BR><BR>CSockAddr CBlockSocket::GetHostByName(const char* pchName, const USHORT ushPort /* = 0 */)<BR>{<BR> hostent* pHostEnt = gethostbyname(pchName);<BR> if (pHostEnt == NULL)<BR> {<BR> throw new CBlockSocketException("GetHostByName");<BR> }<BR> ULONG* pulAddr = (ULONG*) pHostEnt->h_addr_list[0];<BR> SOCKADDR_IN sockTemp;<BR> sockTemp.sin_family = AF_INET;<BR> sockTemp.sin_port = htons(ushPort);<BR> sockTemp.sin_addr.s_addr = *pulAddr;<BR> return sockTemp;<BR>}<BR><BR>const char* CBlockSocket::GetHostByAddr(LPCSOCKADDR psa)<BR>{<BR> hostent* pHostEnt = gethostbyaddr((char*)&((LPSOCKADDR_IN) psa)->sin_addr, 4, AF_INET);<BR> if(pHostEnt == NULL)<BR> {<BR> throw new CBlockSocketException("GetHostByAddr");<BR> }<BR> return pHostEnt->h_name;<BR>}<BR>
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:hf 回复日期:2002-10-29 17:22:32
<br>内容:那就麻烦你帮我找找,看看问题出在哪,调试的时候,客户程序在接收完文件长度后接受文件数据时出现CBlockSocketException
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
<font color=red>答案被接受</font><br>回复者:中国娃娃 回复日期:2002-10-29 17:56:08
<br>内容:晕,差点被你害死!----我写了两个进程,但始终没办法连上。<BR><BR>看了半天连接部分。<BR><BR><BR>有两处可疑点:<BR>CSockAddr sbServer=CSockAddr("202.127.205.153",1020);<BR>try<BR>{<BR>CBlockSocket mysocket;<BR>mysocket.Create();<BR>mysocket.Connect(sbServer);<BR>CLHCDApp *app;<BR>app=(CLHCDApp *)AfxGetApp( ); <BR>char *DataBuf;<BR>char filelen[20];<BR>int uiFileLen;<BR>mysocket.Write(app->netfilename,60,10);<BR>int len;<BR>len=0;<BR>len=mysocket.Read(filelen,20,10);<BR>if (len==2)<BR>{<BR> ::AfxMessageBox("服务器上数据文件不存在");<BR>}<BR>else<BR>{<BR>uiFileLen=atoi(filelen);//不能保证此时filelen一定是以0为结束符,因此有可能造成转换后的值是一个不正确的值<BR>mysocket.Read(DataBuf,uiFileLen,100);//DataBuf尚未分配内存<BR>。。。。。
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:hf 回复日期:2002-10-29 18:05:57
<br>内容:非常感谢你的答案。问题确实出在DataBuf尚未分配内存,非常感谢<BR>
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:中国娃娃 回复日期:2002-10-29 18:08:04
<br>内容:不客气,相互学习吧,你的程序写的挺好的!
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -