各位大侠:
    最近我在学VC下的SOCKET开发,有几点疑问希望大家指点一下:
    1、使用Windows Sockets API开发时需要包含winsock.h|winsock2.h,并导入ws2_32.lib,而使用MFC中的CAsyncSocket类开发时需要包含什么头文件,导入什么库?还有就是使用winsock.h|winsock2.h中的API开发时,其API的名称是什么,就是win32API或是Windows Sockets API?    2、Windows Sockets 的版本常见的有1.1和2.2,不过我看见有些代码如下:
    WORD version = MAKEWORD(2, 0);
   int iRet = WSAStartup(version, &wsaData);
   意思是使用2.0版本的Windows Sockets 吗?   3、Windows Sockets 中经常提到一个阻塞钩子是什么意思,怎么使用?我猜是不是当某个网络事件发生时直接调用阻塞钩子(一般为某个窗口函数?)进行处理?如果是这样,阻塞钩子是不是应该先针对某种事件注册(怎么注册),而且阻塞钩子是由谁调用的(是由WINDOWS系统|应用程序本身?)?   请大家多多指点,非常感谢!

解决方案 »

  1.   

    最近也在研究,我就说一下 不知道对不对.
    <afxsock.h> 
    这个是MFC的socket类用到的头文件. 对应的初始化函数是  AfxSocketInit() ; 组塞钩子? 没听过.. 有阻塞模式与非阻塞模式之分. I/O模型(通信模型?) 有几种,MFC的类封装了的是WSAAsyncSelect模型.
    <windows网络编程> 这本书值得一看.
      

  2.   

    使用SOCKET编程时,只需要进行加载套接字库,进行版本协商,这个需要在StdAfx头文件中添加#include "Afxsock.h"的头文件即可.
    if (!AfxSocketInit())   //加载套接字库,进行版本的协商
    {
    AfxMessageBox("加载套接字库失败! ");
    return FALSE;
    }
    别的就不再需要了,下面是创建一个基于UDP协议的套接字
    SOCKET m_uSocket;
    m_uSocket = socket(AF_INET, SOCK_DGRAM, 0);
    SOCKADDR_IN addrSock;   //地址结构体变量
    addrSock.sin_family = AF_INET;
    addrSock.sin_port = htons(7000);
    addrSock.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    bind(m_uSocket, (SOCKADDR *)&addrSock, sizeof(SOCKADDR));   //绑定到端口
      

  3.   

    还有在接收消息时,SOCKET的recvfrom()是一个阻塞函数,一般的处理方法是另外创建一个线程,用这个线程去不断的接收数据,然后通过消息机制让主窗体进行处理。
    其实有简单点的方法,创建一继承自CSocket的类,在该类中重写OnReceive方法,此方法只要有数据到便会自动运行..... 然后类似上面进行处理
      

  4.   

            阻塞是在把应用程序从Berkeley套接口环境中移植到Windows环境中的一个主
    要焦点。阻塞是指唤起一个函数,该函数直到相关操作完成时才返回。由于操作可
    能需要任意长的时间才能完成,于是问题就出现了。最明显的一个例子就是recv(),
    这个函数会一直处于阻塞状态直到收到对方系统发送的数据。在Berkeley套接口模
    型中,一个套接口的操作的缺省行为是阻塞方式的,除非程序员显式地请求该操作
    为非阻塞方式。我们强烈推荐程序员在尽可能的情况下使用非阻塞方式(异步方式)
    的操作。因为非阻塞方式的操作能够更好地在非占先的Windows环境下工作。程序
    员应该在绝对必要的时候才采用阻塞方式。而且在你必须使用阻塞方式的操作前仔
    细阅读并理解这一部分。
            即使在阻塞方式下,有些操作(例如bind(),getsockopt(),getpeername())也会立

    完成。对于这些操作,阻塞方式和非阻塞方式并没有什么两样。其他一些操作(例
    如recv())可能立刻完成,也可能需要阻塞一段随机的时间才能完成。这都取决于
    不同的传输情况。当用于阻塞套接口时,这些操作被认为是工作于阻塞方式的,所
    有会阻塞的例程在以前或以后的列表中都打上了星号作标记。
            在Windows Sockets实现中,一个无法立刻完成的阻塞操作是按如下方式处理
    的。DLL先初始化操作,然后进入一个循环,在循环中发送收到的任何信息-为了
    使在必要时把处理器交给其他线程,然后检查Windows Sockets功能是否完成。如果
    功能完成了,或者WSACancelBlockingCall()被唤起,阻塞操作以一个适当的返回值
    结束。完整的关于这种机制的描述,请参见5.3.13节,WSASetBlockingHook(),这
    一部分还包括了对于各种函数伪代码的讨论。
            如果一个正在运行某一阻塞操作的进程收到了一个Windows消息,那么应用程
    序有可能试图发出另一个Windows Sockets调用,由于很难安全地处理这种情形,
    Windows Sockets规范不支持这种应用程序的工作方式。在这种情况下,有两个函数
    可以帮助程序员。WSAIsBlocking()可以用来确定在该进程上是否有阻塞的Windows 
    Sockets调用。WSACancelBlookingCall()可以用来取消在线的阻塞调用,如果有的话。
    任何其他的Windows Sockets函数如果在这种情况下被调用,则会失败并返回错误代
    码WSAEINPROGRESS。要强调的是,这一限制适用于所有阻塞和非阻塞的操作。
            虽然这种机制对于简单的应用程序已经足够了,但这不能支持高级应用程序的
    复杂的消息发送要求。(例如,那些MDI模型的用户)对于这样的应用程序,Windows 
    Sockets API设计了WSASetBlockingHook()函数,这个函数可以允许程序员定义特殊
    的阻塞钩子来代替上面讨论的缺省消息发送例程。
            只有在以下都为真时,Windows Sockets DLL才调用阻塞钩子函数:例程是被定
    义为可以阻塞的,指定的套接口也是阻塞套接口,而且请求不能被立刻完成。(套
    接口是被缺省地设为阻塞方式的,但IOCTL FIONBIO和WSAAsyncSelect()都可以
    把套接口设置成为非阻塞模式)。如果应用程序只使用非阻塞方式的套接口,而且
    使用WSAAsyncSelect()和/或WSAAsyncGetXByY()例程,而不是使用select()和/或
    getXbyY()例程,那么阻塞钩子函数就永远也不会被调用,应用程序也不用再操心由
    于阻塞钩子函数而带来的重入问题。
            如果一个应用程序在唤起异步或非阻塞方式调用时使用了一个内存对象的指针
    (例如一个缓冲区,或者一个全程变量)作为参数,那么应用程序要保证那个对象
    在Windows Sockets实现的整个操作中都可得到并使用。应用程序不能再唤起可能影
    响到内存唤射或寻址能力的其他的Windows函数。在多线程系统中,应用程序也有
    责任使用某种同步机制来协调对内存对象的存取。Windows Sockets实现不能,也不
    会提出这种事情。没有遵守这条规则,所可能产生的后果已不在规范讨论的范围之
    内。
      

  5.   

    感谢大家的指点,我想问问如果我在一个自定义类中重载CAsyncSocket的onreceive函数,如果在最后没有调用基类CAsyncSocket的onreceive函数,有没有什么问题?基类函数是用来完成什么功能的?
      

  6.   

    vcScholar ,你说的:“SOCKET的recvfrom()是一个阻塞函数,一般的处理方法是另外创建一个线程,用这个线程去不断的接收数据,然后通过消息机制让主窗体进行处理。”这是什么意思?是不是为了主进程不被阻塞?
    “然后通过消息机制让主窗体进行处理”?是不是调用阻塞函数的进程发消息,什么情况下会触发消息发送,发送什么消息给谁,“主窗体进行处理”处理什么?最好给个例子,谢谢!hosin,你说的:“在Windows Sockets实现中,一个无法立刻完成的阻塞操作是按如下方式处理的。DLL先初始化操作,然后进入一个循环,在循环中发送收到的任何信息-为了 
    是在必要时把处理器交给其他线程”这话是什么意思?那个循环是不是类似于一个独立于应用中所有线程的“检测进程”,它会首先接收到发送给应用中所有线程的消息,接着它会检测Windows Sockets功能是否完成,如果功能完成了,或者WSACancelBlockingCall()(这个函数被谁调用?)被唤起,阻塞操作以一个适当的返回值结束。那如果阻塞操作没有完成呢?它会怎么处理?设置的阻塞钩子是不是就是指的那个循环?
      

  7.   

    socket 1.0是有阻塞控制这种东西类似WSACancelBlockingCall这种东西但是在第二版之后便将其取消了。
    所以在编写网络应用的时候要注意所使用的socket版本不同版本之间所使用的api稍有不同
      

  8.   

    没有MFC的基础,看来我要好好学习一下MFC了。