Search results for 'UDP Send'. 1 post(s) found.

  1. 2007/08/28 UDP Send and Receive Using CAsyncSocket
2007/08/28 10:42

UDP Send and Receive Using CAsyncSocket


The following is sample code showing use of CAsyncSocket to send and receive UDP packets. I used the ClassWizard to create a class (CUDPSocket) derived from CAsyncSocket. The derived class does little more than override OnReceive. The derived class is used in the application's document.


Sample Code


File 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:\r\n%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:\r\n%s", ErrorMessage);
        AfxMessageBox(Message);
        m_Message = "Send failed";
    }
    else
        m_Message = "Data sent";

    UpdateAllViews(NULL, 8, NULL);
}

BOOL CSendReceiveDocument::SaveModified()
{
    return TRUE;
}
Trackback 3 Comment 0

Trackback : Cannot send a trackbact to this post.

  1. Subject different money making ideas

    Tracked from moneyideas 2010/01/28 22:40 delete

    moneyideas

  2. Subject different money making ideas

    Tracked from moneyideas 2010/01/29 06:57 delete

    moneyideas

  3. Subject different money making ideas

    Tracked from moneyideas 2010/01/31 16:44 delete

    moneyideas