头文件
afxsock.h
AfxSocketInit() 函数必须在使用socket之前实现
继承关系
class CSocket : public CAsyncSocket
class CAsyncSocket : public CObject
客户端- 构造一个CSocket对象。使用该对象调用Create函数创建底层SOCKET句柄,因为客户端不需要绑定任何端口和地址, 所以用默认参数即可调用Connect函数将套接字对象连接到服务器套接字,指定服务器地址和端口号
流程:
socket()
create()
connect()
receive() / send()
close()
代码实现:
// 初始化 AfxSocketInit(); // 创建 CSocket 对象 CSocket aSocket; // 初始化 CSocket 对象, 因为客户端不需要绑定任何端口和地址, 所以用默认参数即可 if ( ! aSocket.Create()) { char szMsg[1024] = {0}; sprintf(szMsg, "create faild: %d", aSocket.GetLastError()); AfxMessageBox(szMsg); return; } // 连接指定的地址和端口 if (aSocket.Connect(strIP, nPort)) { char szRecValue[1024] = {0}; //发送内容给服务器 aSocket.Send(strText, strText.GetLength()); //接收服务器发送回来的内容(该方法会阻塞, 在此等待有内容接收到才继续向下执行) aSocket.Receive((void *)szRecValue, 1024); AfxMessageBox(szRecValue); } else { char szMsg[1024] = {0}; sprintf(szMsg, "create faild: %d", aSocket.GetLastError()); AfxMessageBox(szMsg); } // 关闭 aSocket.Close();服务端
- 构造一个CSocket对象。使用该对象调用Create函数创建底层SOCKET句柄,在Create调用中指定端口(不需要再调用bind函数,因为create中已经调用bind),或者直接使用bind函数,指定端口调用Listen开始监听来自客户端的连接尝试。收到连接请求后,通过调用Accept接受它。
流程:
socket()
bind() or create()
listen()
accept()
receive() / send()
close()
注意:
使用Create创建,因为容易会出现10048错误
解决方案:
BOOL bOptVal = TRUE; int bOptLen = sizeof(BOOL); //设置Socket的选项, 解决10048错误必须的步骤 aSocket.SetSockOpt(SO_REUSEADDR, ( void * ) & bOptVal, bOptLen, SOL_SOCKET);
代码实现:
//初始化Winscok if (!AfxSocketInit()) { AfxMessageBox(IDP_SOCKETS_INIT_FAILED); return 1; } //socket------------------------------------------------ CSocket aSocket, serverSocket; //调用Socket函数,最好不要使用aSocket.Create创建,因为容易会出现10048错误 if (!aSocket.Socket()) { char szError[256] = {0}; sprintf(szError, "Create Faild: %d", GetLastError()); AfxMessageBox(szError); return 1; } //绑定端口 if (!aSocket.Bind(nPort)) { char szError[256] = {0}; sprintf(szError, "Bind Faild: %d", GetLastError()); AfxMessageBox(szError); return 1; } BOOL bOptVal = TRUE; int bOptLen = sizeof(BOOL); //设置Socket的选项, 解决10048错误必须的步骤 aSocket.SetSockOpt(SO_REUSEADDR, ( void * ) & bOptVal, bOptLen, SOL_SOCKET); //监听 if ( ! aSocket.Listen( 10 )) { char szError[256] = {0}; sprintf(szError, "Listen Faild: %d", GetLastError()); AfxMessageBox(szError); return 1; } //接收外部连接 if(!aSocket.Accept(serverSocket)) { return 1; } char szRecvMsg[256] = {0}; //接收客户端内容:阻塞 serverSocket.Receive(szRecvMsg, 256); //发送内容给客户端 serverSocket.Send("Have Receive The Msg", 50); //关闭 aSocket.Close(); serverSocket.Close();CSocket类定义
// CSocket头文件定义 class CSocket : public CAsyncSocket { DECLARE_DYNAMIC(CSocket); private: CSocket(const CSocket& rSrc); // 没有实现 void operator=(const CSocket& rSrc); // 没有实现 // 构造 public: CSocket(); BOOL Create(UINT nSocketPort = 0, int nSocketType=SOCK_STREAM, LPCTSTR lpszSocketAddress = NULL); // Attributes public: BOOL IsBlocking(); static CSocket* PASCAL FromHandle(SOCKET hSocket); BOOL Attach(SOCKET hSocket); // Operations public: void CancelBlockingCall(); // Overridable callbacks protected: virtual BOOL onMessagePending(); // Implementation public: int m_nTimeOut; virtual ~CSocket(); static int PASCAL ProcessAuxQueue(); virtual BOOL Accept(CAsyncSocket& rConnectedSocket, SOCKADDR* lpSockAddr = NULL, int* lpSockAddrLen = NULL); virtual void Close(); virtual int Receive(void* lpBuf, int nBufLen, int nFlags = 0); virtual int Send(const void* lpBuf, int nBufLen, int nFlags = 0); int SendChunk(const void* lpBuf, int nBufLen, int nFlags); protected: friend class CSocketWnd; BOOL* m_pbBlocking; int m_nConnectError; 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); static void PASCAL AuxQueueAdd(UINT message, WPARAM wParam, LPARAM lParam); virtual BOOL PumpMessages(UINT uStopFlag); #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; #endif };CAsyncSocket类定义
// CAsyncSocket class CAsyncSocket : public CObject { DECLARE_DYNAMIC(CAsyncSocket); private: CAsyncSocket(const CAsyncSocket& rSrc); // no implementation void operator=(const CAsyncSocket& rSrc); // no implementation // Construction public: CAsyncSocket(); BOOL Create(UINT nSocketPort = 0, int nSocketType=SOCK_STREAM, long lEvent = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_ConNECT | FD_CLOSE, LPCTSTR lpszSocketAddress = NULL); BOOL CreateEx(ADDRINFOT* pAI, long lEvent = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_ConNECT | FD_CLOSE); // Attributes public: SOCKET m_hSocket; operator SOCKET() const; BOOL Attach(SOCKET hSocket, long lEvent = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_ConNECT | FD_CLOSE); SOCKET Detach(); BOOL GetPeerName(CString& rPeerAddress, UINT& rPeerPort); BOOL GetPeerName(SOCKADDR* lpSockAddr, int* lpSockAddrLen); BOOL GetPeerNameEx(CString& rPeerAddress, UINT& rPeerPort); BOOL GetSockName(CString& rSocketAddress, UINT& rSocketPort); BOOL GetSockName(SOCKADDR* lpSockAddr, int* lpSockAddrLen); BOOL GetSockNameEx(CString& rSocketAddress, UINT& rSocketPort); BOOL SetSockOpt(int nOptionName, const void* lpOptionValue, int nOptionLen, int nLevel = SOL_SOCKET); BOOL GetSockOpt(int nOptionName, void* lpOptionValue, int* lpOptionLen, int nLevel = SOL_SOCKET); static CAsyncSocket* PASCAL FromHandle(SOCKET hSocket); static int PASCAL GetLastError(); // Operations public: virtual BOOL Accept(CAsyncSocket& rConnectedSocket, SOCKADDR* lpSockAddr = NULL, int* lpSockAddrLen = NULL); BOOL Bind(UINT nSocketPort, LPCTSTR lpszSocketAddress = NULL); BOOL Bind (const SOCKADDR* lpSockAddr, int nSockAddrLen); BOOL BindEx(ADDRINFOT* pAI); virtual void Close(); BOOL Connect(LPCTSTR lpszHostAddress, UINT nHostPort); BOOL Connect(const SOCKADDR* lpSockAddr, int nSockAddrLen); BOOL ConnectEx(ADDRINFOT* pAI); BOOL IOCtl(long lCommand, DWORD* lpArgument); BOOL Listen(int nConnectionBacklog=5); 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); int ReceiveFromEx(void* lpBuf, int nBufLen, CString& rSocketAddress, UINT& rSocketPort, int nFlags = 0); enum { receives = 0, sends = 1, both = 2 }; BOOL ShutDown(int nHow = sends); 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); int SendToEx(const void* lpBuf, int nBufLen, UINT nHostPort, LPCTSTR lpszHostAddress = NULL, int nFlags = 0); BOOL AsyncSelect(long lEvent = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_ConNECT | FD_CLOSE); // Overridable callbacks protected: virtual void onReceive(int nErrorCode); virtual void onSend(int nErrorCode); virtual void onOutOfBandData(int nErrorCode); virtual void onAccept(int nErrorCode); virtual void onConnect(int nErrorCode); virtual void onClose(int nErrorCode); // Implementation public: virtual ~CAsyncSocket(); static CAsyncSocket* PASCAL LookupHandle(SOCKET hSocket, BOOL bDead = FALSE); static void PASCAL AttachHandle(SOCKET hSocket, CAsyncSocket* pSocket, BOOL bDead = FALSE); static void PASCAL DetachHandle(SOCKET hSocket, BOOL bDead = FALSE); static void PASCAL KillSocket(SOCKET hSocket, CAsyncSocket* pSocket); static void PASCAL DoCallBack(WPARAM wParam, LPARAM lParam); BOOL Socket(int nSocketType=SOCK_STREAM, long lEvent = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_ConNECT | FD_CLOSE, int nProtocolType = 0, int nAddressFormat = PF_INET); #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; #endif protected: friend class CSocketWnd; 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); };流程说明
序号
服务端
客户端
1
构造一个套接字
CAsyncSocket sockServer
构造一个套接字
CAsyncSocket sockClient
2
创建SOCKET句柄,绑定到指定的端口
sockServer.Create(nPort);
创建SOCKET句柄,使用默认参数
sockClient.Create();
3
启动监听,时刻准备接收连接请求
sockServer.Listen();
4
请求链接服务器
sockClient.Connect(strAddress,nPort)
5
构造一个新的空套接字
CAsyncSocket sockRecv;
接收连接
sockServer.Accept(sockRecv);
6
接收数据
sockRecv.Receive(pBuffer,nLen);
发送连接
sockClient.Send(pBuffer,nLen);
7
发送数据
sockRecv.Send(pBuffer,nLen);
接收数据
sockClient.Receive(pBuffer,nLen);
8
关闭套接字对象
sockRecv.Close();
关闭套接字对象
sockClient.Close();
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)