📄 hwsocket.h
字号:
#pragma once
#include "winsock2.h"
#include "String.h"
/*
这是一个模拟 MFC CSocket 的类,在使用该类前要用以下代码来初始化:
WSADATA wsaData;
if( WSAStartup( MAKEWORD(2,0), &wsaData) != 0)
AfxMessageBox ( _T("WSAStartup() failed") );
在程序结束时用以下代码来清理:
WSACleanup( );
*/
/****************************************************************************************************************
投稿说明:
****************************************************************************************************************/
#define NOTE_CHwSocket \
" ◆◆◆ 《模仿 MFC 中的 CAsyncSocket 类写的一个网络通信类 CHwSocket》◆◆◆\r\n\
MFC 中提供两个用于网络编程的类分别为异步的 CAsyncSocket 类和同步的 CSocket 类,这两个类用来编写网络通信程序时非常方便,但也存在一些问题,例如:\
不能跨线程访问、程序发布时使用静态连接 MFC 时也有问题、默认使用了窗口来接受消息,在无窗口的程序中也有问题,这些问题我一直没有解决,如果有高手\
知道解决方法敬请告知,我的 E-Mail 地址是:chrys@163.com。\r\n\
为了编程方便,我这里将 Socket APIs 封装成一个类似 CAsyncSocket 接口的类,可以在任意线程中访问,也可以静态连接 MFC,另外可控性比 MFC 中的两个\
Socket类好多了。我还为 CHwSocket 类编写了详细的测试代码,可以进行 TCP 服务器/客户端数据通信,也可以进行 UDP 数据通信,还可以收发 UDP 广播数据报。\r\n\
你可以任意修改复制本代码,但请保留这段文字不要修改。\r\n\
希望我能为中国的软件行业尽一份薄力!\r\n\
\r\n\
◆◆◆ 作者 ◆◆◆\r\n\
谢红伟 · chrys · chrys@163.com · http://www.howa.com.cn\r\n\
\r\n\
◆◆◆ 日期 ◆◆◆\r\n\
2007-09-23 00:29:12\r\n"
// 句柄是否有效
#ifndef HANDLE_IS_VALID
#define HANDLE_IS_VALID(h) ( (HANDLE)(h!=NULL) && (HANDLE)(h) != INVALID_HANDLE_VALUE )
#endif
class DLL_INTERNAL CHwSocket
{
public:
CHwSocket ();
~CHwSocket();
BOOL Create(UINT nSocketPort = 0, int nSocketType=SOCK_STREAM, LPCTSTR lpszSocketAddress = NULL);
BOOL SetAsBroadcastSocket ();
BOOL SetNonblocking ();
BOOL Bind(UINT nSocketPort, LPCTSTR lpszSocketAddress = NULL);
BOOL Bind (const SOCKADDR* lpSockAddr, int nSockAddrLen);
void Attach(SOCKET hSocket);
SOCKET Detach();
BOOL Listen(int nConnectionBacklog);
BOOL GetPeerName(CString& rPeerAddress, UINT& rPeerPort);
BOOL GetPeerName(SOCKADDR* lpSockAddr, int* lpSockAddrLen);
BOOL GetSockName(CString& rSocketAddress, UINT& rSocketPort);
BOOL GetSockName(SOCKADDR* lpSockAddr, int* lpSockAddrLen);
virtual BOOL Accept(CHwSocket& rConnectedSocket,SOCKADDR* lpSockAddr = NULL, int* lpSockAddrLen = NULL);
virtual void Close();
BOOL Connect(LPCTSTR lpszHostAddress, UINT nHostPort);
BOOL Connect(const SOCKADDR* lpSockAddr, int nSockAddrLen);
virtual int Receive(void* lpBuf, int nBufLen, int nFlags = 0);
int ReceiveFrom(void* lpBuf, int nBufLen,
CString& rSocketAddress, UINT& rSocketPort, int nFlags = 0);
int ReceiveFrom(void* lpBuf, int nBufLen,
SOCKADDR* lpSockAddr, int* lpSockAddrLen, int nFlags = 0);
virtual int Send(const void* lpBuf, int nBufLen, int nFlags = 0);
int SendTo(const void* lpBuf, int nBufLen,
UINT nHostPort, LPCTSTR lpszHostAddress = NULL, int nFlags = 0);
int SendTo(const void* lpBuf, int nBufLen,
const SOCKADDR* lpSockAddr, int nSockAddrLen, int nFlags = 0);
enum { receives = 0, sends = 1, both = 2 };
BOOL ShutDown(int nHow = sends);
BOOL GetSockOpt(int nOptionName, void* lpOptionValue, int* lpOptionLen, int nLevel)
{ return (SOCKET_ERROR != getsockopt(m_hSocket, nLevel, nOptionName, (LPSTR)lpOptionValue, lpOptionLen)); }
BOOL SetSockOpt(int nOptionName, const void* lpOptionValue, int nOptionLen, int nLevel)
{ return (SOCKET_ERROR != setsockopt(m_hSocket, nLevel, nOptionName, (LPCSTR)lpOptionValue, nOptionLen)); }
BOOL IOCtl(long lCommand, DWORD* lpArgument)
{ return (SOCKET_ERROR != ioctlsocket(m_hSocket, lCommand, lpArgument)); }
SOCKET m_hSocket;
protected:
virtual BOOL ConnectHelper(const SOCKADDR* lpSockAddr, int nSockAddrLen);
virtual int ReceiveFromHelper(void* lpBuf, int nBufLen,
SOCKADDR* lpSockAddr, int* lpSockAddrLen, int nFlags);
virtual int SendToHelper(const void* lpBuf, int nBufLen,
const SOCKADDR* lpSockAddr, int nSockAddrLen, int nFlags);
private:
BOOL Socket(int nSocketType=SOCK_STREAM, int nProtocolType = 0, int nAddressFormat = PF_INET);
};
DLL_INTERNAL CString GetSocketAddressAndPort(CHwSocket &sock, BOOL bPeer=TRUE, CString *pcsAddress=NULL, USHORT *pnPort=NULL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -