WINDOWS平台下的SOCKET聊天程序

上次写了个DOS平台下的,觉得功能比较弱,也步好用,这次作了个基于MFC的

闲话少说,开始写代码吧

1.先进一个基于对话框的MFC应用程序,对话框界面如下图所示

2.在stdafx.h中加入#include <Afxsock.h>,CApp类的InitInstance()中加入如下代码

if(!::AfxSocketInit())
 {
  AfxMessageBox("加载动态链接库失败!");
  return false;
 }

3.在主对话框类中加入一个私有变量SOCKET m_socket,加入一个成员函数

BOOL CComDlg::InitSocket()
{
 m_socket = socket(AF_INET,SOCK_DGRAM,0);
 if(INVALID_SOCKET == m_socket)
 {
  MessageBox("初始化套接字失败!");
  return false;
 }
 SOCKADDR_IN sockAddr;
 sockAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
 sockAddr.sin_family = AF_INET;
 sockAddr.sin_port = htons(7000);
    int result;
 result = ::bind(m_socket,(sockaddr*)&sockAddr,sizeof(sockaddr));
 if(SOCKET_ERROR == result)
 {
  MessageBox("绑定套接字失败!");
  ::closesocket(m_socket);
  return false;
 }
 return true;

}

4.在OnInitDialog()中加入一些代码,为了大家看清楚,整个的都拷上了

BOOL CComDlg::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
 InitSocket();
 com *c = new com();
 c->m_hWnd = m_hWnd;
 c->m_socket = m_socket;
    HANDLE hThread = ::CreateThread(NULL,0,Thread,(LPVOID)c,NULL,NULL);
 ::CloseHandle(hThread);
 return TRUE;  // return TRUE  unless you set the focus to a control
}

红颜色的是加的代码

5.在RESOURCE.H中定义一个消息#define UM_RECEIVE    WM_USER+1

在对话框类中加入相应的消息响应函数的声明和实现

声明:afx_msg void OnReceive(WPARAM wParam,LPARAM lParam);

实现:void CComDlg::OnReceive(WPARAM wParam,LPARAM lParam)
{
 CString strRecv = (char*)lParam;
    CString temp;
 GetDlgItemText(IDC_EDIT_RECV,temp);
 strRecv += "/r/n";
 strRecv += temp;
 SetDlgItemText(IDC_EDIT_RECV,strRecv);
}

6.因为在OnInitDialog()中创立了一个子线程,所以必须要在对话框类中加入一个静态的线程处理函数

声明:static DWORD WINAPI Thread(LPVOID lpParameter);

实现:DWORD WINAPI CComDlg::Thread(LPVOID lpParameter)
{
 SOCKET m_socket = ((com*)lpParameter)->m_socket;
 HWND   m_hWnd   = ((com*)lpParameter)->m_hWnd;
 SOCKADDR_IN sockFrom;
 int len = sizeof(sockaddr);
 char recvBuf[100];
 char tempBuf[100];
 while(true)
 {
  ::recvfrom(m_socket,recvBuf,100,0,(sockaddr*)&sockFrom,&len);
  sprintf(tempBuf,"%s says: %s",inet_ntoa(sockFrom.sin_addr),recvBuf);
  ::PostMessage(m_hWnd,UM_RECEIVE,0,(LPARAM)tempBuf);
 }
 
 return 0;
}

7.添加BUTTOnDWORD WINAPI CComDlg::Thread(LPVOID lpParameter)
{
 SOCKET m_socket = ((com*)lpParameter)->m_socket;
 HWND   m_hWnd   = ((com*)lpParameter)->m_hWnd;
 SOCKADDR_IN sockFrom;
 int len = sizeof(sockaddr);
 char recvBuf[100];
 char tempBuf[100];
 while(true)
 {
  ::recvfrom(m_socket,recvBuf,100,0,(sockaddr*)&sockFrom,&len);
  sprintf(tempBuf,"%s says: %s",inet_ntoa(sockFrom.sin_addr),recvBuf);
  ::PostMessage(m_hWnd,UM_RECEIVE,0,(LPARAM)tempBuf);
 }
 
 return 0;
}

7.添加BUTTON的单击消息相应函数

void CComDlg::OnButton1()
{
 // TODO: Add your control notification handler code here
    DWORD dwIP;
 CString strSend;
 ((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS1))->GetAddress(dwIP);
 GetDlgItemText(IDC_EDIT_SEND,strSend);
    SOCKADDR_IN sockAddr;
 sockAddr.sin_addr.S_un.S_addr = htonl(dwIP);
 sockAddr.sin_family = AF_INET;
 sockAddr.sin_port = htons(7000);
    sendto(m_socket,strSend,strlen(strSend)+1,0,(sockaddr*)&sockAddr,sizeof(sockaddr));
 SetDlgItemText(IDC_EDIT_SEND,"");
}

到这里,整个的代码架构终于告一段落了,大家可以做一下,搞清楚了之后,肯定大有收获啊,

累了,睡了!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值