关注中....顺便提一个问题,怎样知道socket接收完毕了呢???

解决方案 »

  1.   

    使用线程参数,LPVOID可指向自定义的信息结构。
      

  2.   

    to superrg:
       我想我是用的udp,用recvfrom一次应能接受完。
    to autopvision:
       你能具体点吗?你说的是工作线程吧?
      

  3.   

    首先,如果你用的是异步事件,或者异步选择,或者重叠IO的IO模型
    那么就不一定要使用多线程了(你这里是异步选择模型)如果你非要使用多线程,可以这样
    假如你使用的是套节字类(比如csocket),那么最好在用户界面线程中使用
    方法是:先定义一个CSocket 对象m_sock和一个套节字SOCKET sock;
    在用户界面线程初始化的时候
    BOOL 就是中帮定这个套节子
    BOOL CSockThread::InitInstance()
    {
        m_sock.Attach(sock);
        return TRUE;
    }如果你自己做异步选择事件的类
    可以这样,从cwnd派生一个类csockethwnd
    加入成员变量SOCKET m_socket;
    然后使用wsaasyncselect注册异步事件,窗口句柄就选择csockethwnd类内部的窗口句柄就是。
    然后自己添加消息映射,处理网络事件
    建立一个cWinThread的派生类
    在改派生类中添加csockethwnd对象,并在线程初始化的时候create这个对象
    并初始化套节字,这样就可以在用户界面线程中使用异步选择套节字。
      

  4.   

    to dash(千分散尽复还来):
    不是用UDP,用tcp/ip,如果出现超时,就很难判断是否已经接收完了...
      

  5.   

    to florist2000(善良的石头):
    能不能做成没有界面的呀??我想做一个服务程序,没有界面的,好像不能使用任何MFC类了...
      

  6.   

    florist2000(善良的石头),你还记得我吧。  硕士答辩开始了吗,祝你成功。我大概看懂你说的方法,有一点小疑问,create了csocketwnd以后,岂不是
    要出来一个窗口?
    另外,你认为不用使用多线程吗?
      

  7.   

    to  dash(千分散尽复还来) 
    当然是需要一个窗口了,因为你使用的是异步选择模型
    实际上你使用MFC套节字类的时候,同样也是要创建一个窗口的
    (因为要消息机制嘛)
    这里,你把窗口的属性改为不可见就是了,MFC套节子类也是这样做的。我嘛?硕士论文还没写呢。想做完一个东西后再写,我明年毕业的。to  superrg(秀华) (  ) 
    不要界面?不要MFC类?那很容易实现了。
    其实你就采用异步事件模型就是。int WSAEventSelect来实现如果你不想使用WINDOWS的扩展IO方式,WINDOWs也支持传统的select()
    那么就都可以只使用工作者线程来完成
    另外,一个窗体并不占用你多少资源的
    呵呵,你要知道一个button控件就是一个窗体派生来的窗口
    不要想的那么恐怖。 
      

  8.   

    to florist2000(善良的石头):
    这么说来,多开一个线程就需要多一个窗体了???
      

  9.   

    to florist2000(善良的石头)
       不好意思,我还以为你今年毕业呢。我中科院肯定考不上了,下半年工作,
    很是郁闷呀。
       我大概知道程序怎么做了,非常感谢你的帮助。我现在在科技楼2楼混机子
    上机,有空来玩呀
      

  10.   

    to superrg(秀华):
       你是不是要做服务器程序呀?推荐一个地方:www.sockaddr.com
       如果你还想我这个贴子讨论,我现在就不结贴了
      

  11.   

    呵呵,没有关系啊,大家都是同校校友
    (考研没有你想的那么重要呢,先工作再说夜不错的啊)
    to  superrg(秀华) 
    有什么问题写我得email了
    [email protected]下了,各位再见
      

  12.   

    谢谢,我先看看,有问题我再给石头兄弟发mail....
      

  13.   

    换一个接口吧,可选择事件选择接口WSAEventSelect()
      

  14.   

    工作者线程:
    UINT receive_thread(LPVOID lParam)
    {
    SOCKET sock;
    SOCKADDR_IN saUdpServ, saUdpCli;
    INT err, nSize;
    BOOL fBroadcast = TRUE;
    SWCMD cmd;
    //创建一个套接字(一个指向传输提供者的句柄)
    //参数一:AF_INET:协议的地址家族(互连网协议)
    //参数二:_SOCKET_DGRAM(套接字类型)
        sock = socket(AF_INET, SOCK_DGRAM, 0);
        if ( INVALID_SOCKET ==  sock)
        {
    printf( _T("接收SOCK出错!-0\7\7\7") );
    return 0;
        }
        //用于在一个套接字级别或者由协议决定的级别上设置套接字选项
    if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(CHAR *)&fBroadcast,sizeof(BOOL))\
    ==SOCKET_ERROR)
        {
    printf( _T("接收SOCKET出错!-1\7\7\7") );
    return 0;
        } int nrevbuf=256000;
        if(setsockopt(sock,SOL_SOCKET,SO_RCVBUF,(CHAR *)&nrevbuf,sizeof(int))\
    ==SOCKET_ERROR)
        {
    printf( _T("接收SOCKET出错!-1\7\7\7") );
    return 0;
        }    // bind to the specified port.
        saUdpServ.sin_family = AF_INET;
        saUdpServ.sin_addr.s_addr = htonl(INADDR_ANY);
        saUdpServ.sin_port = htons(var.global.receive_port);    err = bind(sock, (SOCKADDR FAR *)&saUdpServ, sizeof (SOCKADDR_IN));
        if ( SOCKET_ERROR == err )
        {
    printf( _T("接收SOCKET出错!-2\7\7\7") );
    return 0;
        }    // receive a datagram on the bound port number.
        nSize = sizeof ( SOCKADDR_IN );
    while( TRUE )
    { err = recvfrom (sock,
     ( char* )&cmd,
     sizeof( SWCMD ),
     0,
     (SOCKADDR FAR *) &saUdpCli,
     &nSize
     );
    if ( SOCKET_ERROR == err )
    {
                             .............
                       }
                       else
                       {
                           PostThreadMessage 
                          (var.global.process_thread_id , 0 , 0 ,
                            (LPARAM)sw );
                        }
                   }
      

  15.   

    UINT receive_thread(LPVOID lParam)
    {
    SOCKET sock;
    SOCKADDR_IN saUdpServ, saUdpCli;
    INT err, nSize;
    BOOL fBroadcast = TRUE;
    SWCMD cmd;
    //创建一个套接字(一个指向传输提供者的句柄)
    //参数一:AF_INET:协议的地址家族(互连网协议)
    //参数二:_SOCKET_DGRAM(套接字类型)
        sock = socket(AF_INET, SOCK_DGRAM, 0);
        if ( INVALID_SOCKET ==  sock)
        {
    printf( _T("接收SOCK出错!-0\7\7\7") );
    return 0;
        }
        //用于在一个套接字级别或者由协议决定的级别上设置套接字选项
    if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(CHAR *)&fBroadcast,sizeof(BOOL))\
    ==SOCKET_ERROR)
        {
    printf( _T("接收SOCKET出错!-1\7\7\7") );
    return 0;
        } int nrevbuf=256000;
        if(setsockopt(sock,SOL_SOCKET,SO_RCVBUF,(CHAR *)&nrevbuf,sizeof(int))\
    ==SOCKET_ERROR)
        {
    printf( _T("接收SOCKET出错!-1\7\7\7") );
    return 0;
        }    // bind to the specified port.
        saUdpServ.sin_family = AF_INET;
        saUdpServ.sin_addr.s_addr = htonl(INADDR_ANY);
        saUdpServ.sin_port = htons(var.global.receive_port);    err = bind(sock, (SOCKADDR FAR *)&saUdpServ, sizeof (SOCKADDR_IN));
        if ( SOCKET_ERROR == err )
        {
    printf( _T("接收SOCKET出错!-2\7\7\7") );
    return 0;
        }    // receive a datagram on the bound port number.
        nSize = sizeof ( SOCKADDR_IN );
    while( TRUE )
    { err = recvfrom (sock,
     ( char* )&cmd,
     sizeof( SWCMD ),
     0,
     (SOCKADDR FAR *) &saUdpCli,
     &nSize
     );
    PostThreadMessage(var.global.process_thread_id , 0 , 0 , (LPARAM)sw );
    ....................