以文本方式查看主题

-  计算机科学论坛  (http://bbs.xml.org.cn/index.asp)
--  『 C/C++编程思想 』  (http://bbs.xml.org.cn/list.asp?boardid=61)
----  一个菜鸟关于完成端口的问题[求助]  (http://bbs.xml.org.cn/dispbbs.asp?boardid=61&rootid=&id=51815)


--  作者:king1994gw
--  发布时间:8/25/2007 5:49:00 PM

--  一个菜鸟关于完成端口的问题[求助]
我是用delphi编的 由于网上只有收数据的模型 我想把它该成发送数据的 但是却不能发送 想请问各位高手哪里出错了 谢谢
unit Unit2;

interface
uses Windows, unit1, WinSock, Sysutils;
const
  port=5150;
  data_bufsize=8192;
type
  lpvoid=pointer;
  lpper_io_operation_data=^per_io_operation_data;
  per_io_operation_data=packed record
    overlapped:overlapped;
    databuf:twsabuf;
    buffer:array[0..data_bufsize]of char;
    bytessend:dword;
    bytesrec:dword;
  end;
  lpper_handle_data=^per_handle_data;
  per_handle_data=packed record
    socket:tsocket;
  end;

  procedure main;

implementation

function serverworkerthread(completionportid:lpvoid):dword;stdcall;forward;

procedure printf(fmt:string;num:integer);
begin
  writeln(format(fmt,[num]));
end;
procedure main;
var
  internetaddr:sockaddr_in;
  listen:tsocket;
  accept:tsocket;
  completionport:thandle;
  systeminfo:system_info;
  perhandledata:lpper_handle_data;
  periodata:lpper_io_operation_data;
  i:integer;
  recvbytes,sendbytes:dword;
  flags:dword;
  threadid:dword;
  wsadata:twsadata;
  ret:dword;
  threadhandle:thandle;
begin
  ret:=wsastartup($0202,wsadata);
  if (ret<>0) then
  begin
    printf('wsas %d',ret);
    exit;
  end;
  completionport:=createiocompletionPort(INVALID_HANDLE_VALUE,0,0,0);
  if (CompletionPort=0) then
  begin
    printf('createioerror:%d',getlasterror());
    exit;
  end;
  getsysteminfo(systeminfo);
  for i:=0 to systeminfo.dwNumberOfProcessors*2-1 do
  begin
    threadhandle:=createthread(nil,0,@serverworkerthread,pointer(completionport),0,threadid);
    if (threadhandle=0) then
    begin
      printf('c',getlasterror());
      exit;
    end;
    closehandle(threadhandle);
  end;
  listen:=wsasocket(af_inet,sock_stream,0,nil,0,wsa_flag_overlapped);
  if (listen=invalid_socket) then
  begin
    printf('wsa',wsagetlasterror());
    exit;
  end;
  internetaddr.sin_family:=af_inet;
  internetaddr.sin_addr.S_addr:=inet_addr(pchar('192.168.0.2'));
  internetaddr.sin_port:=htons(port);
  perhandledata:=lpper_handle_data(globalalloc(gptr,sizeof(per_handle_data)));
  if (perhandledata=nil) then
  begin
    printf('glo',wsagetlasterror());
    exit;
  end;
  printf('socket numble%d',accept);
  perhandledata.socket:=listen;
  if (createiocompletionport(listen,completionport,dword(perhandledata),0)=0) then
  begin
    printf('createiocp%d',wsagetlasterror());
    exit;
  end;
  periodata:=lpper_io_operation_data(globalalloc(gptr,sizeof(per_io_operation_data)));
  if (periodata=nil) then
  begin
    printf('glo%d',wsagetlasterror());
    exit;
  end;
    zeromemory(@periodata.overlapped,sizeof(overlapped));
    periodata.bytessend:=0;
    periodata.bytesrec:=0;
    periodata.databuf.len:=data_bufsize;
    periodata.buffer:='wudi';
    periodata.databuf.buf:=@periodata.buffer;
    flags:=0;
    if (wsasend(listen,@(periodata.databuf),1,@sendbytes,0,@(periodata.overlapped),nil)=socket_error) then
    begin
      if (wsagetlasterror<>error_io_pending) then
      begin
        printf('wsarecvfailed%d',wsagetlasterror());
        exit;
      end
    end;
  end;

function serverworkerthread(completionportid:lpvoid):dword;stdcall;
var
   CompletionPort: THANDLE;
   BytesTransferred: DWORD ;
   PerHandleData: LPPER_HANDLE_DATA ;
   PerIoData: LPPER_IO_OPERATION_DATA ;
   SendBytes, RecvBytes: DWORD;
   Flags: DWORD ;
begin
  completionport:=thandle(completionportid);
  result:=0;
  while(true) do
  begin
    if (getqueuedcompletionstatus(completionport,bytestransferred,dword(perhandledata),poverlapped(periodata),infinite)=false) then
    begin
      printf('get%d',getlasterror());
      exit;
    end;
    if (bytestransferred=0) then
    begin
      printf('closingsocket%d\',perhandledata.socket);
      if (closesocket(perhandledata.socket)=socket_error) then
      begin
        printf('closesocketerror%d',wsagetlasterror());
        exit;
      end;
      globalfree(dword(perhandledata));
      globalfree(dword(periodata));
      continue;
    end;
    if (periodata.bytesrec=0) and (periodata.bytessend=0) then
    begin
      PerIoData.BytesREC:= BytesTransferred;
      periodata.bytessend:= 0;
    end
    else
    begin
      periodata.bytesrec:=0;
      periodata.bytessend:=bytestransferred;
    end;
    if (periodata.bytesrec>periodata.bytessend) then
    begin
      zeromemory(@(periodata.overlapped),sizeof(overlapped));
      periodata.databuf.buf:= periodata.buffer+periodata.bytessend;
      periodata.databuf.len:= periodata.bytesrec-periodata.bytessend;
      printf(periodata.buffer,periodata.databuf.len);
      if (wsasend(perhandledata.socket,@(periodata.databuf),1,@sendbytes,0,@(periodata.overlapped),nil)=socket_error) then
      begin
        if (wsagetlasterror()<>error_io_pending) then
        begin
          printf('wsasend%d',wsagetlasterror());
          exit
        end;
      end;
    end
    else
    begin
      periodata.bytesrec:= 0;
      flags:= 0;
      zeromemory(@(periodata.overlapped),sizeof(overlapped));
      periodata.databuf.len:= data_bufsize;
      periodata.databuf.buf:= @periodata.buffer;
      if (wsasend(perhandledata.socket,@(periodata.databuf),1,@sendbytes,0,@(periodata.overlapped),nil)=socket_error) then
      begin
        if (wsagetlasterror()<>error_io_pending) then
        begin
          if (wsagetlasterror()<>error_io_pending) then
          begin
            printf('wsa%d',wsagetlasterror());
            exit;
          end;
        end;
      end;
    end;
  end;
end;
end.


W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
46.875ms