刚看完成端口有点问题 下面是我网上找来的完成端口模型的代码,我配了个简单的客户端与与完成端口模型通信 客户端第一次能发送数据 但当关掉客户端 再打开客户端与完成端口模型通信 就不能发送数据了 点发送按钮 就直接无响应了 不知道是为什么呀
服务器
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: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:=htonl(inaddr_any);
  internetaddr.sin_port:=htons(port);
  if (bind(listen,internetaddr,sizeof(internetaddr))=socket_error) then
  begin
    printf('bind',wsagetlasterror());
    exit;
  end;
  if (winsock.listen(listen,5)=socket_error) then
  begin
    printf('listen',wsagetlasterror());
    exit;
  end
  else
  begin
    printf('serverlisten',port);
  end;
  while (true) do
  begin
    accept:=wsaaccept(listen,nil,nil,nil,0);
    if (accept=socket_error) then
    begin
      printf('wsaaccept',wsagetlasterror());
      exit;
    end;
    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:=accept;
    if (createiocompletionport(accept,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.databuf.buf:=@periodata.buffer;
    flags:=0;
    if (wsarecv(accept,@(periodata.databuf),1,@recvbytes,@flags,@(periodata.overlapped),nil)=socket_error) then
    begin
      if (wsagetlasterror<>error_io_pending) then
      begin
        printf('wsarecvfailed%d',wsagetlasterror());
        exit;
      end
    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) then
    begin
      PerIoData.BytesREC:= BytesTransferred;
      periodata.bytessend:= 0;
    end
    else
    begin
      periodata.bytessend:= 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;
      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 (wsarecv(perhandledata.socket,@(periodata.databuf),1,@recvbytes,@flags,@(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.
客户端
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,winsock, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
  wsadata:twsadata;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  errorcode:integer;
begin
  errorcode:=wsastartup($0101,wsadata);
  if errorcode<> 0 then
  begin
    showmessage('jiazaifaile');
    exit;
  end;
end;
{ tsocketreadthread }

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  wsacleanup;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  buf:array[0..10] of char;
  rebuf:array[0..10] of char;
  sa:sockaddr_in;
  skc:tsocket;
  ret:integer;
  r:string;
begin
  skc:=socket(pf_inet,sock_stream,ipproto_tcp);
  if skc=socket_error then
  begin
    showmessage('shibai');
    exit;
  end;
  sa.sin_family:=pf_inet;
  sa.sin_port:=htons(5150);
  sa.sin_addr.S_addr:=inet_addr(pchar('192.168.0.2'));
  connect(skc,sa,sizeof(sa));
  r:='hehehe';
  lstrcpy(buf,pchar(r));
  send(skc,buf,10*sizeof(char),0);
  ret:=recv(skc,rebuf,256,0);
  if ret>0 then memo1.Lines.Add(rebuf);

end;

end.[?][?]