vc异步套接字

MFC 创建异步套接字的网络聊天程序

1.首先包含 winsock2.h

2.工程-设置 链接 ws2_32.lib

3.在app类的InitInstance()中加载套接字库 因为要用2.2的版本 所以AfxSocketInit()不用 不过AfxSocketInit加载1.1版本很方便 并且可以省去上面两步骤

BOOL CChat16App::InitInstance()
{
 WSADATA wsaData;
 if(WSAStartup(MAKEWORD(2,2),&wsaData))
 {
  AfxMessageBox("套接字库加载失败");
  return FALSE;
 }
 if (LOBYTE(wsaData.wVersion)!=2||HIBYTE(wsaData.wVersion)!=2)
 {
  AfxMessageBox("套接字库加载版本不一致");
  WSACleanup();
  return FALSE;
 }

4.Dlg类中 加入SOCKET m_sock,CString recvBuf成员

并且写下此代码

BOOL CChat16Dlg::InitSocket()
{
 m_sock=WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,0);
 if (INVALID_SOCKET==m_sock)
 {
  MessageBox("套接字创建失败");
  return FALSE;
 }
 SOCKADDR_IN addr;
 addr.sin_family=AF_INET;
 addr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
 addr.sin_port=htons(6000);

 if(bind(m_sock,(SOCKADDR*)&addr,sizeof(SOCKADDR))==SOCKET_ERROR)
 {
  MessageBox("套接字绑定失败");
  return FALSE;
 }
 if(WSAAsyncSelect(m_sock,m_hWnd,UM_SOCK,FD_READ))  //登记网络事件 等网络读取事件发生以UM_SOCK消息通知对话框窗口
 {
  MessageBox("网络事件登记失败");
  return FALSE;
 }
 return TRUE;
}

5.自定义消息的编写

void CChat16Dlg::OnSock(WPARAM wParam,LPARAM lParam)
{
 CString strTemp;
 WSABUF wsabuf;
 wsabuf.buf=new char[200];
 wsabuf.len=200;
 DWORD recvCz;
 DWORD flags=0;
 SOCKADDR_IN addrFrom;
 int len=sizeof(SOCKADDR);
 CString strFmt;
 HOSTENT *pHost;
 switch(LOWORD(lParam))       
 {
 case FD_READ:
  WSARecvFrom(m_sock,&wsabuf,1,&recvCz,&flags,(SOCKADDR*)&addrFrom,&len,NULL,NULL);
  strTemp=wsabuf.buf;
  delete[] wsabuf.buf;
  strTemp+="\r\n";
//  strFmt.Format("%s:%s",inet_ntoa(addrFrom.sin_addr),strTemp);
  pHost=gethostbyaddr((char*)&addrFrom.sin_addr.S_un.S_addr,4,AF_INET);  //第一个参数要求char*的网络字节序 第二个参数 因为地址族是AF_INET 必须4
  strFmt.Format("%s:%s",pHost->h_name,strTemp);
  recvBuf+=strFmt;
  break;
 }
 SetDlgItemText(IDC_EDIT_RECV,recvBuf);
}

6.

BOOL CChat16Dlg::OnInitDialog()
{
 CDialog::OnInitDialog();

 // 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();           //调用刚刚的函数

7.

发送端 的编写

void CChat16Dlg::OnSendbtn()
{
 // TODO: Add your control notification handler code here
 CString sendBuf;
 WSABUF wsabuf;
 DWORD sendCz;
 SOCKADDR_IN addrTo;
 DWORD dwIp;
 ((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS))->GetAddress(dwIp);
 GetDlgItemText(IDC_EDIT_SEND,sendBuf);
 SetDlgItemText(IDC_EDIT_SEND,"");
 wsabuf.buf=sendBuf.GetBuffer(sendBuf.GetLength()+1);
 wsabuf.len=sendBuf.GetLength()+1;
 addrTo.sin_family=AF_INET;
// addrTo.sin_addr.S_un.S_addr=htonl(dwIp);
 addrTo.sin_port=htons(6000);

 CString strHostName;
 if (GetDlgItemText(IDC_EDIT_HOSTNAME,strHostName),strHostName=="")
 {
  addrTo.sin_addr.S_un.S_addr=htonl(dwIp);
 }
 else
 {
  hostent *pHost=gethostbyname(strHostName);
  addrTo.sin_addr.S_un.S_addr=*((DWORD*)(pHost->h_addr_list[0]));  //h_addr_list[0]是一个字符指针 因为是网络字节序可以先将其转为DWORD* 而后按DWORD类型取值
 }

 if(WSASendTo(m_sock,&wsabuf,1,&sendCz,0,(SOCKADDR*)&addrTo,sizeof(SOCKADDR),NULL,NULL))
 {
  MessageBox("发送失败");
 }
}

8.最后

void CChat16Dlg::OnClose()
{
 // TODO: Add your message handler code here and/or call default
 closesocket(m_sock);  //关闭套接字
 WSACleanup();   //清除加载的版本
 CDialog::OnClose();
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值