您的位置:程序门 -> vc/mfc -> 网络编程



哪位帮我看看 iocp 的代码,为什么出问题,谢谢


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


哪位帮我看看 iocp 的代码,为什么出问题,谢谢[已结贴,结贴人:waini12]
发表于:2007-04-25 14:14:44 楼主
#define     port   5150  
  #define     data_bufsize   8192  
  //   关键项  
  typedef     struct  
      {
      overlapped   overlapped;
      wsabuf   databuf;
      char   buffer[data_bufsize];
      dword   bytessend;
      dword   bytesrecv;
}     per_io_operation_data,     *     lpper_io_operation_data;
typedef     struct    
    {
      socket   socket;
}     per_handle_data,     *     lpper_handle_data;

dword   winapi   serverworkerthread(lpvoid   completionportid);

  void     main(   void   )
    {
      sockaddr_in   internetaddr;
      socket   listen;
      socket   accept;
      handle   completionport;
      system_info   systeminfo;
      lpper_handle_data   perhandledata;
      lpper_io_operation_data   periodata;
        int     i;
      dword   recvbytes;
      dword   flags;
      dword   threadid;
      wsadata   wsadata;
      dword   ret;

        if     ((ret     =     wsastartup(   0x0202   ,     &   wsadata))     !=       0   )
          {
            printf(   "   wsastartup   failed   with   error   %d\n   "   ,   ret);
              return   ;
      }  
 
        //   打开一个空的完成端口  
 
        if     ((completionport     =     createiocompletionport(invalid_handle_value,   null,     0   ,     0   ))     ==     null)
          {
            printf(     "   createiocompletionport   failed   with   error:   %d\n   "   ,   getlasterror());
              return   ;
      }  
 
        //     determine   how   many   processors   are   on   the   system.  
 
      getsysteminfo(   &   systeminfo);

        //     开启cpu个数的2倍个的线程  
 
        for   (i     =       0   ;   i     <     systeminfo.dwnumberofprocessors     *       2   ;   i   ++   )
          {
            handle   threadhandle;

              //     create   a   server   worker   thread   and   pass   the   completion   port   to   the   thread.  
 
              if     ((threadhandle     =     createthread(null,     0   ,   serverworkerthread,   completionport,
                    0   ,     &   threadid))     ==     null)
                {
                  printf(   "   createthread()   failed   with   error   %d\n   "   ,   getlasterror());
                    return   ;
            }  
 
              //     close   the   thread   handle  
              closehandle(threadhandle);
      }  
 
        //   打开一个服务器socket  
 
        if     ((listen     =     wsasocket(af_inet,   sock_stream,     0   ,   null,     0   ,
            wsa_flag_overlapped))     ==     invalid_socket)
          {
            printf(   "   wsasocket()   failed   with   error   %d\n   "   ,   wsagetlasterror());
              return   ;
      }    

      internetaddr.sin_family     =     af_inet;
      internetaddr.sin_addr.s_addr     =     htonl(inaddr_any);
      internetaddr.sin_port     =     htons(port);

        if     (bind(listen,   (psockaddr)     &   internetaddr,     sizeof   (internetaddr))     ==     socket_error)
          {
            printf(   "   bind()   failed   with   error   %d\n   "   ,   wsagetlasterror());
              return   ;
      }  
 
 
        if     (listen(listen,     5   )     ==     socket_error)
          {
            printf(   "   listen()   failed   with   error   %d\n   "   ,   wsagetlasterror());
              return   ;
      }  
 
        //   开始接收从客户端来的连接  
 
        while   (true)
          {
              if     ((accept     =     wsaaccept(listen,   null,   null,   null,     0   ))     ==     socket_error)
                {
                  printf(   "   wsaaccept()   failed   with   error   %d\n   "   ,   wsagetlasterror());
                    return   ;
            }  
 
              //     创建一个关键项用于保存这个客户端的信息,用户接收发送的重叠结构,
              //     还有使用到的缓冲区  
                if     ((perhandledata     =     (lpper_handle_data)   globalalloc(gptr,  
                    sizeof   (per_handle_data)))     ==     null)
                {
                  printf(   "   globalalloc()   failed   with   error   %d\n   "   ,   getlasterror());
                    return   ;
            }  
 
              //     associate   the   accepted   socket   with   the   original   completion   port.  
 
            printf(   "   socket   number   %d   connected\n   "   ,   accept);
            perhandledata   ->   socket     =     accept;

              //   与我们的创建的那个完成端口关联起来,将关键项也与指定的一个完成端口关联  
                if     (createiocompletionport((handle)   accept,   completionport,   (dword)   perhandledata,
                    0   )     ==     null)
                {
                  printf(   "   createiocompletionport   failed   with   error   %d\n   "   ,   getlasterror());
                    return   ;
            }  
 
              //     投递一次接收,由于接收都需要使用这个函数来投递一个接收的准备  
 
              if     ((periodata     =     (lpper_io_operation_data)   globalalloc(gptr,   sizeof   (per_io_operation_data)))     ==     null)
                {
                  printf(   "   globalalloc()   failed   with   error   %d\n   "   ,   getlasterror());
                    return   ;
            }  
 
            zeromemory(   &   (periodata   ->   overlapped),     sizeof   (overlapped));
            periodata   ->   bytessend     =       0   ;
            periodata   ->   bytesrecv     =       0   ;
            periodata   ->   databuf.len     =     data_bufsize;
            periodata   ->   databuf.buf     =     periodata   ->   buffer;

            flags     =       0   ;
              if     (wsarecv(accept,     &   (periodata   ->   databuf),     1   ,     &   recvbytes,     &   flags,
                    &   (periodata   ->   overlapped),   null)     ==     socket_error)
                {
                    if     (wsagetlasterror()     !=     error_io_pending)
                      {
                        printf(   "   wsarecv()   failed   with   error   %d\n   "   ,   wsagetlasterror());
                          return   ;
                  }  
            }  
      }  
}  
  //   工作线程  
  dword   winapi   serverworkerthread(lpvoid   completionportid)
    {
      handle   completionport     =     (handle)   completionportid;
      dword   bytestransferred;
      lpoverlapped   overlapped;
      lpper_handle_data   perhandledata;
      lpper_io_operation_data   periodata;
      dword   sendbytes,   recvbytes;
      dword   flags;
     
        while   (true)
          {
              //   完成端口有消息来了  
                if     (getqueuedcompletionstatus(completionport,     &   bytestransferred,
                  (lpdword)   &   perhandledata,   (lpoverlapped     *   )     &   periodata,   infinite)     ==       0   )
                {
                  printf(   "   getqueuedcompletionstatus   failed   with   error   %d\n   "   ,   wsagetlasterror());
                    return       0   ;
            }  
 
 
              //   是不是有人退出了  
 
              if     (bytestransferred     ==       0   )
                {
                  printf(   "   closing   socket   %d\n   "   ,   perhandledata   ->   socket);

                    if     (closesocket(perhandledata   ->   socket)     ==     socket_error)
                      {
                        printf(   "   closesocket()   failed   with   error   %d\n   "   ,   wsagetlasterror());
                          return       0   ;
                  }  
 
                  globalfree(perhandledata);
                  globalfree(periodata);
                    continue   ;
            }  
 
              //
 
              if     (periodata   ->   bytesrecv     ==       0   )
                {
                  periodata   ->   bytesrecv     =     bytestransferred;
                  periodata   ->   bytessend     =       0   ;
            }  
              else  
                  {
                  periodata   ->   bytessend     +=     bytestransferred;
            }  
 
              if     (periodata   ->   bytesrecv     >     periodata   ->   bytessend)
                {

                    //     post   another   wsasend()   request.
                    //     since   wsasend()   is   not   gauranteed   to   send   all   of   the   bytes   requested,
                    //     continue   posting   wsasend()   calls   until   all   received   bytes   are   sent.  
 
                  zeromemory(   &   (periodata   ->   overlapped),     sizeof   (overlapped));

                  periodata   ->   databuf.buf     =     periodata   ->   buffer     +     periodata   ->   bytessend;
                  periodata   ->   databuf.len     =     periodata   ->   bytesrecv     -     periodata   ->   bytessend;

                    if     (wsasend(perhandledata   ->   socket,     &   (periodata   ->   databuf),     1   ,     &   sendbytes,     0   ,
                          &   (periodata   ->   overlapped),   null)     ==     socket_error)
                      {
                          if     (wsagetlasterror()     !=     error_io_pending)
                            {
                              printf(   "   wsasend()   failed   with   error   %d\n   "   ,   wsagetlasterror());
                                return       0   ;
                        }  
                  }  
            }  
              else  
                  {
                  periodata   ->   bytesrecv     =       0   ;

                    //     now   that   there   are   no   more   bytes   to   send   post   another   wsarecv()   request.  
 
                  flags     =       0   ;
                  zeromemory(   &   (periodata   ->   overlapped),     sizeof   (overlapped));

                  periodata   ->   databuf.len     =     data_bufsize;
                  periodata   ->   databuf.buf     =     periodata   ->   buffer;

                    if     (wsarecv(perhandledata   ->   socket,     &   (periodata   ->   databuf),     1   ,     &   recvbytes,     &   flags,
                          &   (periodata   ->   overlapped),   null)     ==     socket_error)
                      {
                          if     (wsagetlasterror()     !=     error_io_pending)
                            {
                              printf(   "   wsarecv()   failed   with   error   %d\n   "   ,   wsagetlasterror());
                                return       0   ;
                        }  
                  }  
            }  
      }  
}
发表于:2007-04-25 14:15:131楼 得分:0
客户部分

  #include     <   winsock2.h   >  
#include     <   windows.h   >  
#include     <   stdio.h   >  

  #define     port   5150  
  #define     data_bufsize   8192  

  //   关键项  
  typedef     struct  
      {
      overlapped   overlapped;
      wsabuf   databuf;
      char   buffer[data_bufsize];
      dword   bytessend;
      dword   bytesrecv;
}     per_io_operation_data,     *     lpper_io_operation_data;

int   main()
{

if     ((ret     =     wsastartup(   0x0202   ,     &   wsadata))     !=       0   )
          {
            printf(   "   wsastartup   failed   with   error   %d\n   "   ,   ret);
              return   ;
      }  

socket   s   =   ::wsasocket   (af_inet,sock_stream,0,0,0,wsa_flag_overlapped);

sockaddr_in   sin;
sin.sin_family   =   af_inet;
sin.sin_port   =   ::htons   (5150);
sin.sin_addr.s_un.s_addr   =   ::inet_addr   ( "127.0.0.1 ");

::connect(s,reinterpret_cast <sockaddr*> (&sin),sizeof(sockaddr_in));
 
lpper_io_operation_data   p   =     (lpper_io_operation_data)   globalalloc(gptr,   sizeof   (per_io_operation_data));
zeromemory(   &   (p   ->   overlapped),     sizeof   (overlapped));

        p-> databuf.len     =     strlen( "hello,world ");
p-> databuf.buf   =     p-> buffer   ;  
strcpy(&p   ->   databuf.buf   [0]   , "hello,world ");

dword   dwrec;

//   这里的发送函数调用成功,但是服务器接收不到数据
        if     (wsasend(s,     &   (p   ->   databuf),     1   ,     &   dwrec,     0   ,&(p   ->   overlapped),   null)     ==     socket_error)
{
if     (wsagetlasterror()     !=     error_io_pending)
{
printf(   "   wsasend()   failed   with   error   %d\n   "   ,   wsagetlasterror());
                        return       0   ;
                }  
}  


::sleep   (10000);

return   0;
}
发表于:2007-04-27 11:43:152楼 得分:0
没有人帮忙吗?
发表于:2007-04-27 12:13:573楼 得分:10
你得说说你出了什么问题啊
发表于:2007-04-27 13:33:054楼 得分:0
客户端无法   发送数据给服务器端


快速检索

最新资讯
热门点击