APIsocket,VS2010,windows非阻塞模式异步套接字编程(看孙鑫视频有感)
来源:互联网 发布:sd卡格式化后数据还在 编辑:程序博客网 时间:2024/06/11 21:34
作者在windows+vs2010写的,UDP,异步套接字。
写非阻塞模式程序时候发现问题。
1.VC6.0里可以将wMsg的消息响应函数返回值设置为void,但是在VS2010里面会报错error C2440: “static_cast”: 无法从“void (__thiscall CChatMessageDlg::* )(WPARAM,LPARAM)”转换为“LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM)”。
为解决问题,在VS2010中将返回值设置为LRESULT。响应函数的参数lParam的低字节(用LOWORD(lParam)来取)里面保存了网络事件的类型。
2.采用WSA的socket的函数写以上程序的时候,出现了内存错误。作者插了断点,发现消息响应的WSARecvFrom没有接收到信息,准备接收信息的WSABUF变量仍然为空。
为解决问题,作者将有WSA前缀的socket函数换成socket函数(WSAAsyncSelect函数保留),运行OK。
下面附上代码:
windows socket有两种模式阻塞式和非阻塞式。
阻塞模式下,windows socket 会一直等待下去,线程会一直阻塞在这里。所以可以考虑使用多线程,创建线程,在线程中死循环,不断recvfrom(),然后PostMessage(),发送消息到消息队列,消息在主线程处理。(参考孙鑫老师Lesson15的Chat程序)
写非阻塞模式程序时候发现问题。
1.VC6.0里可以将wMsg的消息响应函数返回值设置为void,但是在VS2010里面会报错error C2440: “static_cast”: 无法从“void (__thiscall CChatMessageDlg::* )(WPARAM,LPARAM)”转换为“LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM)”。
为解决问题,在VS2010中将返回值设置为LRESULT。响应函数的参数lParam的低字节(用LOWORD(lParam)来取)里面保存了网络事件的类型。
2.采用WSA的socket的函数写以上程序的时候,出现了内存错误。作者插了断点,发现消息响应的WSARecvFrom没有接收到信息,准备接收信息的WSABUF变量仍然为空。
为解决问题,作者将有WSA前缀的socket函数换成socket函数(WSAAsyncSelect函数保留),运行OK。
下面附上代码:
1.初始化套接字函数
bool CChatMessageDlg::InitSocket(void){m_socket=socket(AF_INET,SOCK_DGRAM,0);//增加的扩展函数 与 socket()一样if ( INVALID_SOCKET ==m_socket){MessageBox("socket failed!");}SOCKADDR_IN addrSock;addrSock.sin_addr.S_un.S_addr=htonl(INADDR_ANY);addrSock.sin_family=AF_INET;addrSock.sin_port=htons(6000);if(SOCKET_ERROR==bind(m_socket,(sockaddr*)&addrSock,sizeof(sockaddr))){closesocket(m_socket);MessageBox("bind 失败");return false;}if (SOCKET_ERROR==WSAAsyncSelect(m_socket,m_hWnd,WM_SOCK,FD_READ)){MessageBox("注册网路读取事件 失败!");return false;}return true;}该函数直接在OnInitDialog中调用即可。
2.Dialog.h头文件中define 消息
#define WM_SOCK WM_USER+13.Message_Map中
ON_MESSAGE(WM_SOCK,&CChatMessageDlg::OnSock)4.消息响应函数
LRESULT CChatMessageDlg::OnSock(WPARAM wParam,LPARAM lParam){//MessageBox(" onsock");switch(LOWORD(lParam)){case FD_READ:{char recvbuf[200];char tempbuf[300];int retval;sockaddr_in addrfrom;int len=sizeof(addrfrom);retval=recvfrom(m_socket,recvbuf,200,0,(sockaddr*)&addrfrom,&len);if (SOCKET_ERROR==retval){return false;}CString str;CString strTemp;str.Format("%s说:%s",inet_ntoa(addrfrom.sin_addr),recvbuf);str+="\r\n";GetDlgItemText(IDC_EDIT_RECV,strTemp);//取出原有的消息str+=strTemp;SetDlgItemText(IDC_EDIT_RECV,str);break;}}return 0;}
5.响应发送按钮的函数
void CChatMessageDlg::OnBnClickedBtnSend(){//MessageBox("send ms");// TODO: 在此添加控件通知处理程序代码DWORD dwIP;//接收IP地址((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS1))->GetAddress(dwIP);SOCKADDR_IN addrTo;addrTo.sin_addr.S_un.S_addr=htonl(dwIP);//转化为网络字节序addrTo.sin_family=AF_INET;addrTo.sin_port=htons(6000);CString strSend;GetDlgItemText(IDC_EDIT_SEND,strSend);int len;len=strSend.GetLength()+1;sendto(m_socket,strSend,strSend.GetLength()+1,0,(sockaddr*)&addrTo,sizeof(addrTo));SetDlgItemText(IDC_EDIT_SEND,"");//清空 发送编辑框}
6.运行结果
- APIsocket,VS2010,windows非阻塞模式异步套接字编程(看孙鑫视频有感)
- 套接字编程非阻塞
- Windows CE下的非阻塞套接字编程
- Windows Socket 异步编程(非阻塞模式)
- Windows Socket 异步编程(非阻塞模式)
- Windows Socket 异步编程(非阻塞)
- 5.1 套接字的非阻塞模式
- 套接字的非阻塞模式
- 套接字的非阻塞模式
- 设置套接字的非阻塞模式
- 网络编程基础--非阻塞套接字
- 套接字的阻塞模式和非阻塞模式
- 非阻塞套接字
- Windows Socket 异步编程(非阻塞模式) -- Select回送示例
- Windows Socket 异步编程(非阻塞模式) -- Select回送示例
- Windows Socket 异步编程(非阻塞模式) -- Select回送示例
- Windows Socket 异步编程(非阻塞模式) -- Select回送示例
- Linux socket编程之阻塞套接字和非阻塞套接字
- 黑马程序员-控制台下的连续四则计算器
- WC bug
- Pro Android学习笔记(四三):Fragment(8):再谈Transaction和管理器
- 关于C#发送邮件模块
- POJ P1182 食物链
- APIsocket,VS2010,windows非阻塞模式异步套接字编程(看孙鑫视频有感)
- 并发 并行
- 拍好宝贝照片后,PS三秒抠出宝贝图片
- HTML 存储自定义对象
- crond命令
- iframe的各项参数
- oracle 10g基本配置(doc下进入数据库)
- 查找的几种简单算法
- javascript返回顶部效果