• 用UDP实现聊天功能


    // SK003Dlg.cpp : implementation file
    //
     
    #include "stdafx.h"
    #include "SK003.h"
    #include "SK003Dlg.h"
     
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif
     
    #define WM_RECVTEXT (WM_USER + 100)
    /////////////////////////////////////////////////////////////////////////////
    // CAboutDlg dialog used for App About
     
    class CAboutDlg : public CDialog
    {
    public:
     CAboutDlg();
     
    // Dialog Data
     //{{AFX_DATA(CAboutDlg)
     enum { IDD = IDD_ABOUTBOX };
     //}}AFX_DATA
     
     // ClassWizard generated virtual function overrides
     //{{AFX_VIRTUAL(CAboutDlg)
     protected:
     virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
     //}}AFX_VIRTUAL
     
    // Implementation
    protected:
     //{{AFX_MSG(CAboutDlg)
     //}}AFX_MSG
     DECLARE_MESSAGE_MAP()
    };
     
    CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
    {
     //{{AFX_DATA_INIT(CAboutDlg)
     //}}AFX_DATA_INIT
    }
     
    void CAboutDlg::DoDataExchange(CDataExchange* pDX)
    {
     CDialog::DoDataExchange(pDX);
     //{{AFX_DATA_MAP(CAboutDlg)
     //}}AFX_DATA_MAP
    }
     
    BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
     //{{AFX_MSG_MAP(CAboutDlg)
      // No message handlers
     //}}AFX_MSG_MAP
    END_MESSAGE_MAP()
     
    /////////////////////////////////////////////////////////////////////////////
    // CSK003Dlg dialog
     
    CSK003Dlg::CSK003Dlg(CWnd* pParent /*=NULL*/)
     : CDialog(CSK003Dlg::IDD, pParent)
    {
     //{{AFX_DATA_INIT(CSK003Dlg)
     m_strTarget = _T("");
     m_strUser = _T("");
     //}}AFX_DATA_INIT
     // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    }
     
    void CSK003Dlg::DoDataExchange(CDataExchange* pDX)
    {
     CDialog::DoDataExchange(pDX);
     //{{AFX_DATA_MAP(CSK003Dlg)
     DDX_Control(pDX, IDC_LIST_MESSAGE, m_MessageList);
     DDX_Control(pDX, IDC_EDIT_WRITE, m_EditWrite);
     DDX_Text(pDX, IDC_EDIT_TARGET, m_strTarget);
     DDX_Text(pDX, IDC_EDIT_USER, m_strUser);
     //}}AFX_DATA_MAP
    }
     
    BEGIN_MESSAGE_MAP(CSK003Dlg, CDialog)
     //{{AFX_MSG_MAP(CSK003Dlg)
     ON_WM_SYSCOMMAND()
     ON_WM_PAINT()
     ON_WM_QUERYDRAGICON()
     ON_BN_CLICKED(IDC_BUTTON_SEND, OnButtonSend)
     ON_BN_CLICKED(IDC_BUTTON_COMFIRM, OnButtonComfirm)
     ON_MESSAGE(WM_RECVTEXT, OnRecvText)
     //}}AFX_MSG_MAP
    END_MESSAGE_MAP()
     
    /////////////////////////////////////////////////////////////////////////////
    // CSK003Dlg message handlers
     
    BOOL CSK003Dlg::OnInitDialog()
    {
     CDialog::OnInitDialog();
     
     // Add "About..." menu item to system menu.
     
     // IDM_ABOUTBOX must be in the system command range.
     ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
     ASSERT(IDM_ABOUTBOX < 0xF000);
     
     CMenu* pSysMenu = GetSystemMenu(FALSE);
     if (pSysMenu != NULL)
     {
      CString strAboutMenu;
      strAboutMenu.LoadString(IDS_ABOUTBOX);
      if (!strAboutMenu.IsEmpty())
      {
       pSysMenu->AppendMenu(MF_SEPARATOR);
       pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
      }
     }
     
     // Set the icon for this dialog. The framework does this automatically
     // when the application's main window is not a dialog
     SetIcon(m_hIcon, TRUE); // Set big icon
     SetIcon(m_hIcon, FALSE); // Set small icon
     
     // TODO: Add extra initialization here
     WSADATA wsadata;
     WSAStartup(MAKEWORD(2, 2), &wsadata);
     m_bCreateSocket = FALSE;
     EnableCtrl(FALSE);
     return TRUE; // return TRUE unless you set the focus to a control
    }
     
    void CSK003Dlg::OnSysCommand(UINT nID, LPARAM lParam)
    {
     if ((nID & 0xFFF0) == IDM_ABOUTBOX)
     {
      CAboutDlg dlgAbout;
      dlgAbout.DoModal();
     }
     else
     {
      CDialog::OnSysCommand(nID, lParam);
     }
    }
     
    // If you add a minimize button to your dialog, you will need the code below
    // to draw the icon. For MFC applications using the document/view model,
    // this is automatically done for you by the framework.
     
    void CSK003Dlg::OnPaint()
    {
     if (IsIconic())
     {
      CPaintDC dc(this); // device context for painting
     
      SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
     
      // Center icon in client rectangle
      int cxIcon = GetSystemMetrics(SM_CXICON);
      int cyIcon = GetSystemMetrics(SM_CYICON);
      CRect rect;
      GetClientRect(&rect);
      int x = (rect.Width() - cxIcon + 1) / 2;
      int y = (rect.Height() - cyIcon + 1) / 2;
     
      // Draw the icon
      dc.DrawIcon(x, y, m_hIcon);
     }
     else
     {
      CDialog::OnPaint();
     }
    }
     
    // The system calls this to obtain the cursor to display while the user drags
    // the minimized window.
    HCURSOR CSK003Dlg::OnQueryDragIcon()
    {
     return (HCURSOR) m_hIcon;
    }
     
    BOOL CSK003Dlg::CreateUDPSocket(USHORT uPort)
    {
     SOCKET sock;
        SOCKADDR_IN addr;
        sock = socket(AF_INET, SOCK_DGRAM, 0);
     
     int optval = 1;
     if(SOCKET_ERROR == setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&optval, sizeof(optval)))
     {
      closesocket(sock);
      return FALSE;
     }
     
     addr.sin_addr.s_addr = INADDR_ANY;
     addr.sin_family = AF_INET;
     addr.sin_port = htons(uPort);
        if(SOCKET_ERROR == bind(sock, (SOCKADDR*)&addr, sizeof(addr)))
        {
      closesocket(sock);
            AfxMessageBox("绑定端口失败");
            return FALSE;
        }
     m_hSocket = sock;
     return TRUE;
    }
     
    void CSK003Dlg::OnButtonSend()
    {
     // TODO: Add your control notification handler code here
     CString strText;
     m_EditWrite.GetWindowText(strText);
     if(strText.IsEmpty())
     {
      AfxMessageBox("发送信息不能为空!");
      return;
     }
     CString strBuffer;
     strBuffer = m_strName;
     strBuffer += ":";
     strBuffer += strText;
     int nLen = strBuffer.GetLength();
     if(nLen > 4096)
     {
      AfxMessageBox("发送信息的长度太长未能发送!");
      return;
     }
        sendto(m_hSocket, strBuffer.GetBuffer(0), nLen, 0, (SOCKADDR*)&m_addrRemote, sizeof(SOCKADDR_IN));
     strBuffer.ReleaseBuffer();
     
     m_EditWrite.SetWindowText("");
    }
     
    void CSK003Dlg::OnButtonComfirm()
    {
     // TODO: Add your control notification handler code here
     UpdateData(TRUE);
     if(m_strTarget.IsEmpty())
     {
      AfxMessageBox("信息发送的目的地址不能为空.");
      return;
     }
     if(m_strUser.IsEmpty())
     {
      AfxMessageBox("用户名不能为空,请填写任意用户名");
      return;
     }
     DWORD dwAddr = inet_addr(m_strTarget);
     m_addrRemote.sin_addr.s_addr = dwAddr;
     m_addrRemote.sin_family = AF_INET;
     m_addrRemote.sin_port = htons(6517);
     m_strName = m_strUser;
     
     if(!CreateUDPSocket(6517))
     {
      AfxMessageBox("创建UDP套接口失败!");
      return;
     }
     AfxMessageBox("创建UDP套接口成功!");
     CreateThread(NULL, 0, RecvFromThreadProc, this, 0, NULL);
     m_bCreateSocket = TRUE;
     EnableCtrl(TRUE);
    }
     
    DWORD WINAPI RecvFromThreadProc(LPVOID param)
    {
     int nRecv = 0;
     char pBuffer[4097];
     SOCKADDR_IN addr;
     int addrlen = sizeof(addr);
     CSK003Dlg *pMainWnd = (CSK003Dlg*)param;
     while (TRUE)
     {
      memset(pBuffer, 0, 4096);
      nRecv = recvfrom(pMainWnd->m_hSocket, pBuffer, 4096, 0, (sockaddr*)&addr, &addrlen);
      if(nRecv == -1) break;
      pMainWnd->SendMessage(WM_RECVTEXT, 0, (LPARAM)pBuffer);
     }
     return 0L;
    }
     
    LRESULT CSK003Dlg::OnRecvText(WPARAM wParam, LPARAM lParam)
    {
     LPCTSTR lpszText = (LPCTSTR)lParam;
     m_MessageList.AddString(lpszText);
     return 0L;
    }
     
    void CSK003Dlg::EnableCtrl(BOOL bChecked)
    {
     CWnd *pWnd;
     CEdit *pEdit;
     pWnd = GetDlgItem(IDC_BUTTON_COMFIRM);
     pWnd->EnableWindow(!bChecked);
     
     pEdit = (CEdit*)GetDlgItem(IDC_EDIT_TARGET);
     pEdit->SetReadOnly(bChecked);
     
     pEdit = (CEdit*)GetDlgItem(IDC_EDIT_USER);
     pEdit->SetReadOnly(bChecked);
     
     pWnd = GetDlgItem(IDC_BUTTON_SEND);
     pWnd->EnableWindow(bChecked);
     
     pEdit = (CEdit*)GetDlgItem(IDC_EDIT_WRITE);
     pEdit->SetReadOnly(!bChecked);
    }
  • 相关阅读:
    [LeetCode] 101. 对称二叉树
    [LeetCode] 394. 字符串解码!!!!
    USACO Ordered Fractions
    USACO The Castle
    遇到的Mysql的一个坑
    USACO-palsquare 遇到的一个坑
    大整数相乘
    vs2012扩展
    JS实现文字倒计数
    jqAutoComplete 和 knockout
  • 原文地址:https://www.cnblogs.com/liaocheng/p/4243497.html
Copyright © 2020-2023  润新知