UDP Send and Receive Using CAsyncSocket | |||
| |||
Sample CodeFile stdafx.h #pragma once #define VC_EXTRALEAN #include <afxwin.h> #include <afxsock.h> #include <afxcmn.h> File UDPSocket.h class CSendReceiveDocument; class CUDPSocket : public CAsyncSocket { public: CSendReceiveDocument *m_pDocument; // public for debugging CUDPSocket() : m_pDocument(NULL) {}; virtual ~CUDPSocket() {}; void SetDocument(CSendReceiveDocument *pDocument) {m_pDocument=pDocument;}; void Close() {CAsyncSocket::Close();}; // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CUDPSocket) public: virtual void OnReceive(int nErrorCode); //}}AFX_VIRTUAL // Generated message map functions //{{AFX_MSG(CUDPSocket) // NOTE - the ClassWizard will add and remove member functions here. //}}AFX_MSG }; File UDPSocket.cpp void CUDPSocket::OnReceive(int nErrorCode) { CString IPAddress; char Buffer[512]; // Increase size as needed CString Message; DWORD Error; UINT Port; int Size; CAsyncSocket::OnReceive(nErrorCode); if (nErrorCode) { Message.Format("OnReceive nErrorCode: %i", nErrorCode); AfxMessageBox(Message); return; } Size = ReceiveFrom(Buffer, sizeof Buffer, IPAddress, Port); if (!Size || Size == SOCKET_ERROR) { Error = GetLastError(); Message.Format("ReceiveFrom error code: %u", Error); AfxMessageBox(Message); return; } if (m_pDocument) m_pDocument->OnReceive(Buffer, Size, IPAddress, Port); else AfxMessageBox("No document pointer"); } I am using class CSocketAddressIn to simplify use of addresses. The following is the definition. class CSocketAddressIn : sockaddr_in { public: CSocketAddressIn() {ZeroMemory(this, sizeof sockaddr_in);sin_family = AF_INET;}; CSocketAddressIn(u_long Address, u_short Port = 0); void SetAddress(u_long Address) {sin_addr.s_addr = htonl(Address);}; void GetAddress(CString &s) {s=inet_ntoa(sin_addr);}; void SetPort(u_short Port) {sin_port = htons(Port);}; operator sockaddr *() const {return (struct sockaddr *)this;} }; The following is the implementation of the extra constructor: CSocketAddressIn::CSocketAddressIn(u_long Address, u_short Port) { sin_family = AF_INET; sin_addr.s_addr = htonl(Address); sin_port = htons(Port); ZeroMemory(sin_zero, sizeof sin_zero); } The CSendReceiveDocument definition is: class CSendReceiveDocument : public CDocument { protected: DECLARE_DYNCREATE(CSendReceiveDocument) CUDPSocket m_UDPSocket; int m_DataSize; UINT m_rSocketPort; CString m_rSocketAddress; static const CString m_NoPath; CString m_Message, m_ReceivedData; CTime m_TimeReceived; // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CSendReceiveDocument) public: virtual BOOL OnOpenDocument(LPCTSTR lpszPathName); virtual void OnCloseDocument(); virtual BOOL OnNewDocument(); virtual void DeleteContents(); virtual void SetPathName(LPCTSTR lpszPathName, BOOL bAddToMRU = TRUE); protected: virtual BOOL SaveModified(); //}}AFX_VIRTUAL public: CSendReceiveDocument(); virtual ~CSendReceiveDocument() {}; void SendTo(LPCTSTR, DWORD, LPCTSTR); void OnReceive(void * const, int, const CString, UINT); #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; #endif // Generated message map functions protected: //{{AFX_MSG(CSendReceiveDocument) //}}AFX_MSG DECLARE_MESSAGE_MAP() }; The CSendReceiveDocument implementation is: const CString CSendReceiveDocument::m_NoPath = "None"; CSendReceiveDocument::CSendReceiveDocument() : m_DataSize(0), m_rSocketPort(0) { CString Path; m_UDPSocket.SetDocument(this); CSocketAddressIn SocketAddressIn(INADDR_ANY); SocketAddressIn.GetAddress(Path); Path += " : 0"; SetPathName(Path); } BOOL CSendReceiveDocument::OnOpenDocument(LPCTSTR lpszPathName) { CString ErrorMessage, Message, PathName(lpszPathName), SocketAddress, s; int ColonIndex; UINT Port(0); long Events; OnCloseDocument(); if (PathName == m_NoPath) return TRUE; ColonIndex = PathName.Find(':'); if (ColonIndex == -1) SocketAddress = PathName; else { SocketAddress = PathName.Left(ColonIndex); s = PathName.Mid(ColonIndex+1); s.TrimLeft(); Port = strtoul(s, NULL, 10); } Events = FD_READ | FD_WRITE | FD_CONNECT | FD_CLOSE; if (!m_UDPSocket.Create(Port, SOCK_DGRAM, Events, SocketAddress)) { GetErrorMessage(GetLastError(), ErrorMessage); Message.Format("The socket for %s was not created: %s", PathName, ErrorMessage); AfxMessageBox(Message); SetPathName(m_NoPath); m_Message = "Open failed"; UpdateAllViews(NULL, 8, NULL); return FALSE; } SetPathName(PathName); m_Message = "Opened: "; m_Message += PathName; UpdateAllViews(NULL, 1, NULL); SetModifiedFlag(TRUE); return TRUE; } void CSendReceiveDocument::OnCloseDocument() { m_UDPSocket.Close(); // CDocument::OnCloseDocument(); // Don't call; will close view and frame DeleteContents(); SetModifiedFlag(FALSE); } BOOL CSendReceiveDocument::OnNewDocument() { AfxMessageBox("Sorry, "New Document" is not available"); return CDocument::OnNewDocument(); } void CSendReceiveDocument::DeleteContents() { m_DataSize = 0; m_Message.Empty(); m_ReceivedData.Empty(); UpdateAllViews(NULL, 9, NULL); SetTitle(m_NoPath); CDocument::DeleteContents(); } void CSendReceiveDocument::SetPathName(LPCTSTR lpszPathName, BOOL bAddToMRU) { m_strPathName = lpszPathName; ASSERT(!m_strPathName.IsEmpty()); // must be set to something m_bEmbedded = FALSE; SetTitle(lpszPathName); } void CSendReceiveDocument::OnReceive(void *const Buffer, int Size, const CString rSocketAddress, UINT rSocketPort) { m_rSocketPort = rSocketPort; m_rSocketAddress = rSocketAddress; m_DataSize = Size; m_TimeReceived = CTime::GetCurrentTime(); memcpy(m_ReceivedData.GetBuffer(Size), Buffer, Size); m_ReceivedData.ReleaseBuffer(Size); UpdateAllViews(NULL, 2, NULL); } void CSendReceiveDocument::SendTo(LPCTSTR Data, DWORD dwAddress, LPCTSTR Port) { CSocketAddressIn SocketAddress; CString ErrorMessage, Message; int rv; SocketAddress.SetAddress(dwAddress); SocketAddress.SetPort((u_short)strtoul(Port, NULL, 10)); rv = m_UDPSocket.SendTo(Data, strlen(Data), SocketAddress, sizeof SocketAddress, 0); if (rv == SOCKET_ERROR) { GetErrorMessage(GetLastError(), ErrorMessage); Message.Format("The data was not sent: %s", ErrorMessage); AfxMessageBox(Message); m_Message = "Send failed"; } else m_Message = "Data sent"; UpdateAllViews(NULL, 8, NULL); } BOOL CSendReceiveDocument::SaveModified() { return TRUE; } Tags: C++ Client/Server Datagram SOCK_DGRAM UDP UDP Receive UDP Send | |||
| |||
| |||
Login for comment |
SIMILAR POSTS Creating and Using a CAsyncSocket Object to use CAsyncSocket |