用阻塞方式进行通信,recv()函数要等到收到数据才返回,如果不用recv(),怎么判断收到数据,可不可以获得数据长度?
我在win32 dll中调用winsock,没有另外开线程。主界面调用dll收发数据,并对数据进行拼图处理,用阻塞方式会不会来不及?

解决方案 »

  1.   

    使用Select()设置SOCKET,可以知道何时读SOCKET。
      

  2.   

    1. 你最好用非阻塞的select(),如果你你直接调用recv()而没有数据,那么主线程就什么也干不了。
    2. recv()本身就返回受到的数据长度。
      

  3.   

    怎么把阻塞的变成非阻塞的呢?
    ioctlsocket(s,FIOBIO,(unsigned long *) &ul);
      

  4.   

    用WSAAsyncSelect()的话有一个参数是窗口句柄,我的winsock是包装在win32 dll中的,现在并不能够确定应用程序的窗口句柄,怎么办
    而且用WSAAsyncSelect()好像很麻烦,可否给个例子
      

  5.   

    WSAAsyncSelect(*ServerSock,(HWND)lParam,WM_CLIENT_READCOLOSE,FD_READ|FD_CLOSE);LRESULT CClientTestDlg::OnReadClose(WPARAM wParam,LPARAM lParam)
    {
    char *buf = new char[100];
    CString str;
    switch (WSAGETSELECTEVENT(lParam))
    {
    case FD_READ:
    if(recv(ServerSocket,(char *)&msg,sizeof(msg),0) == SOCKET_ERROR)
    {
    list.InsertString(0,"接收数据发生错误。");
    g_eventKill.SetEvent();
    return 0L;
    }
    str.Format("%s",msg.msg);
    list.InsertString(0,str);
    break;
    case FD_CLOSE:
    closesocket(ServerSocket);
    list.InsertString(0,"服务器退出。");
    g_eventKill.SetEvent();
    IsTrue = FALSE;
    break;
    }
    return 0L;
    }
      

  6.   

    unsigned long argp=0;
    bool exit=false;
    while(!exit)
    {
    //先获取套接字消息队列上第一个等待接受的消息的大小
    if((ioctlsocket(m_Sock,FIONREAD,(u_long*)&argp))==SOCKET_ERROR)
    {
    continue;
    }
    if(argp==0)//argp 是你将要接受的消息大小
    continue;
    char *buf=new char[argp+1];
    int msgcount=(int)argp;
    if((recv(m_Sock,buf,(int)argp,0))<=0)
    {
    break;
    }
    argp=0;
                      ......//do your business
                      delete[] buf;
               }
    希望我的程序中一段代码能对你有帮助!
      

  7.   

    另开一线程兼听的话,用堵塞是不是就不会影响主界面程序?具体应该怎么做呢
    目前我socketlisten 和socketrecv放在dll中,由主界面程序调用,实际上是单线程的
      

  8.   

    int nfds = 0;
    fd_set readfds;
    fd_set FAR *writefds = NULL;
    fd_set exceptfds;

    timeval timeout = {5, 0};  readfds.fd_count = nClient;
    for (i=0; i< nClient; i++)
    readfds.fd_array[i] = Client[i]; exceptfds.fd_count = nClient;
    for (i=0; i< nClient; i++)
    exceptfds.fd_array[i] = Client[i];

    int rc = select(nfds, &readfds,  writefds, &exceptfds, &timeout );
    if(rc <= 0)
    {
    continue;
    } for (j=0; j<nClient; j++)
    {
    if(! FD_ISSET(Client[j], &readfds))     //第j个Sockety有数据
    continue;

    SmppRecv(j);   // 接收第j个Socket的数据
      

  9.   

    试图模块分离阿!!最基本的设计模式怎么忘了?界面和只提供界面功能有DLL控制
    界面可以提供函数指针给DLL就行了,但是别忘了,这样就不能用模板类了!
    我个人觉得用线程控制起来比较方便,因为设置参数毕竟是死用,而线程是活用,2者优劣自然一目了然!而且在线程中也可以任意控制SOCKET参数。给我信箱,给你发个设计图!
      

  10.   

    [email protected]
    我的dll只是作为一个服务器程序,把从硬件主机接收到的数据处理以后传给界面程序。界面调用dll 函数对硬件进行控制,并对传上来的工作数据进行图像处理。
    计划把网络通信有关的函数都封装在dll中,减少与界面的相关性。
    楼上有相关的开发经验的话,可否交流交流,我的QQ是10399188