高手指点winsockets非阻塞模式设定的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高手指点winsockets非阻塞模式设定的问题相关的知识,希望对你有一定的参考价值。

网络服务端部分程序代码:
SOCKET server;
sockaddr_in local;
local.sin_family=AF_INET;
local.sin_addr.s_addr=INADDR_ANY;
local.sin_port=htons((u_short)2008);
server=socket(AF_INET,SOCK_STREAM,0);
if(server==INVALID_SOCKET)

MessageBox(NULL,_T("Socket函数失败\r\n"),_T"sockets:"),MB_OK);
return 0;

if(bind(server,(sockaddr*)&local,sizeof(local))!=0)

MessageBox(NULL,_T("Binding action failed\r\n"),_T("sockets:"),MB_OK);
return 0;

if(listen(server,10)!=0)

MessageBox(NULL,_T("The number of guests is over the limitation (10)\r\n"),_T("sockets:"),MB_OK);
return 0;

//设置为非阻塞方式
unsigned int wMsg;
HWND hwnd;
int iErrorCode;
iErrorCode = WSAAsyncSelect(server,hwnd,WM_SOCKET,FD_READ|FD_WRITE|FD_ACCEPT);
if (iErrorCode == SOCKET_ERROR)

MessageBox(NULL,_T("WSAAsyncSelect设定失败!"),_T("socket:"),MB_OK);
return 0;

SOCKET client;
sockaddr_in from;
int fromlen=sizeof(from);
MessageBox(NULL,_T("Now we are waiting for messages from clients\r\n"),_T("sockets:"),MB_OK);
while(true)

char temp[512];
client=accept(server,(struct sockaddr*)&from,&fromlen);
sprintf(temp,"Your IP is %s\r\n",inet_ntoa(from.sin_addr));
WSAAsyncSelect(client,hwnd,WM_SOCKET, FD_READ| FD_WRITE);
if (iErrorCode == SOCKET_ERROR)

MessageBox(NULL,_T("WSAAsyncSelect设定失败!"),_T("socket:"),MB_OK);
break;

send(client,temp,strlen(temp),0);
closesocket(client);

closesocket(server);
WSACleanup();
结果运行时提示:Run-Time Check Failure #3 - The variable 'hwnd' is being used without being defined.
也就是WSAAsyncSelect()函数中的窗口句柄hwnd未初始化,
怎么初始化?
我这样设定非阻塞模式可以吗?
网上讲的非阻塞模式设定比较复杂,本人vc基础太差读起来困难。我其实不需要窗口显示消息的,有没有更简单的设定方法?
程序中漏写了wsastartup这一段,实际程序中已经初始化winsock了
我用的是MFC
我调了一周了还是不行啊。现在就想问WSAAyncselect()函数里hwmd这个变量在哪定义,怎么初始化?

再续:Sadusaga :
我不太懂,好像没有窗口啊。我现在改成了这样:
int i=WSAAsyncSelect(server,m_hWnd,WM_SOCKET,FD_ACCEPT);
if (i== SOCKET_ERROR)

MessageBox("WSAAsyncSelect设定1失败");

对应WM_SOCKET的函数已经编辑好,但是恐怕还没运行到这步:
因为调试后弹出窗口:“WSAAsyncSelect设定1失败!”
是不是hwnd的问题?
这是把hwnd设成全局变量了。
要是在WSAAyncSelect()前定义:
HWND hwnd;
提示:未初始化变量hwnd。
请您帮分析分析。谢谢!!

首先你缺少了WSAStartup,所以后面的socket调用都会失败。
再一个,你提到的hWnd是响应消息WM_SOCKET的窗口句柄,在你的句柄里来处理FD_READ| FD_WRITE以及FD_ACCEPT事件。

如何初始化?
1、如果你是MFC程序,可以在你的对话框或是视图里面来处理,也就是传递他们的句柄。
2、如果是Console程序,那么先Create一个Window,传递他的句柄,在窗口过程里处理事件。

补充:
你想在哪个窗口处理消息就传哪个句柄。

再补充:

那个句柄是有用的,因为你要对socket消息进行处理,所以必须传递一个真实的窗口,而非简单的一个声明。你传递的句柄必须有自己的窗口过程,来处理WM_SOCKET消息。
参考技术A 你程序中已经初始化winsock了
其实非阻塞模式设定也挺简单的,只是WSAAsyncSelect中的参数设错了,hwnd应改为 AfxGetMainWnd()->m_hWnd这样一旦有FD_READ| FD_WRITE事件就会发给主窗口WM_SOCKET消息

如何用C语言 读取内存中的数据 要不要将实模式改为保护模式,实怎么改的呢,希望高手指点

这是我写的读取地址F000:7820处的内容,但是,跟在dos下,用debug看到的结果实不一样的? 请问问题出在哪里?
#include <stdio.h>
#include <stdlib.h>
main()

int i;
unsigned char far*p=(unsigned char far*)0x0007910;
for(i=1;i<=256;i++)

printf(" %02x",*p);
p++;


getch();

是如何在保护模式和实模式之间切换的呢,有没有较为详细的说明啊? 有源码的话,可以给一个吗??

你的程序和Debug中相同的地址实际上是被映射到不同的物理地址空间的,当然你看到的内容不一样了。

Windows是不会让你的程序进入实模式的。

如果你实在感兴趣,这里有让CPU切换模式的代码http://jc.finaleden.com/A/2001-12-10/7366.html,不过它只是表示了CPU进行模式切换的方法,不能在Windows环境之下使用的。

如果对Windows结构感兴趣的话,你需要看更多的Windows系统结构的资料了,关于驱动程序的发展,可以参考:http://funnypig.bokee.com/3235076.html
参考技术A 高手 ,能认识你吗,很想跟你学学C语言

以上是关于高手指点winsockets非阻塞模式设定的问题的主要内容,如果未能解决你的问题,请参考以下文章

selenium 怎么处理模态对话框,网上查了资料,说要重写方法,但看了还是无法解决,希望有高手能指点下,谢

非阻塞方式socket send()返回大小和实际发送大小不一致

JAVA设计模式学习顺序,请高手指点!

arduino 串口如何数据提取变量,请各位高手指点

用fcntl设定socket为非阻塞

安装系统时出现这种情况从来没见过 高手出来指点