Server端:
var
Form1: TForm1;
iHandle: THandle;
GlobalLock: TCriticalSection;
implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
begin
iHandle:= CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0);
end;procedure TForm1.Button2Click(Sender: TObject);
var
Addr: TSockAddr;
begin
iSender:= WSASocket(AF_INET, SOCK_DGRAM, 0, nil, 0, WSA_FLAG_OVERLAPPED);
Addr.sin_family:= AF_INET;
Addr.sin_port:= htons(4545);
Addr.sin_addr.S_addr:= inet_addr('127.0.0.1');
if Bind(iSender, @Addr, Sizeof(Addr)) <> 0 then
begin
ShowMessage('绑定出错');
end;
if iSender <> INVALID_SOCKET then
begin
if CreateIoCompletionPort(iSender, iHandle, 0, 0) <> 0 then
begin
tWorkThread.Create;
end;
end;
end;{ tWorkThread }constructor tWorkThread.Create;
begin
inherited Create(True);
FreeOnTerminate := true;
Resume;
end;procedure tWorkThread.Execute;
var
HandleData: PPerHandleData;
byteRece, Key: DWORD;
OperPosted: boolean;
errCode: integer;
begin
while not Terminated do
begin
if not GetQueuedCompletionStatus(iHandle, byteRece, Key, POverlapped(HandleData), INFINITE) then
begin
errCode:= GetLastError;
if errCode = 6 then
Terminate;
Continue;
end
else
begin
GlobalLock.Enter;
case HandleData.Statu of
ssRecv:
begin
ShowMessage('Recv');
end;
ssSend:
begin
ShowMessage('Send');
end;
end;
GlobalLock.Leave;
end; end;
end;procedure TForm1.FormCreate(Sender: TObject);
var
wsaData: TWSAData;
begin
WSAStartup(makeword(2, 0), wsaData);
end;procedure TForm1.FormDestroy(Sender: TObject);
begin
WSACleanup;
end;initialization
GlobalLock := TCriticalSection.Create;
finalization
GlobalLock.Free;end.Client端:
procedure TForm1.FormCreate(Sender: TObject);
var
wsaData: TWSAData;
begin
WSAStartup(makeword(2, 0), wsaData);
end;procedure TForm1.FormDestroy(Sender: TObject);
begin
WSAcleanup;
end;procedure TForm1.Button1Click(Sender: TObject);
var
addrin: TSockAddr;
tmpPacket: array [0..8191] of byte;
begin
iSender:= Socket(AF_INET, SOCK_DGRAM, 0);
addrin.sin_family:= AF_INET;
addrin.sin_port:= htons(4540);
addrin.sin_addr.S_addr:= inet_addr('127.0.0.1');
if Bind(iSender, @addrin, sizeof(addrin)) <> 0 then
ShowMessage('绑定出错')
else
begin
Sendto(iSender, tmpPacket, 8192, 0, addrin, sizeof(addrin));
end;
end;
var
Form1: TForm1;
iHandle: THandle;
GlobalLock: TCriticalSection;
implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
begin
iHandle:= CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0);
end;procedure TForm1.Button2Click(Sender: TObject);
var
Addr: TSockAddr;
begin
iSender:= WSASocket(AF_INET, SOCK_DGRAM, 0, nil, 0, WSA_FLAG_OVERLAPPED);
Addr.sin_family:= AF_INET;
Addr.sin_port:= htons(4545);
Addr.sin_addr.S_addr:= inet_addr('127.0.0.1');
if Bind(iSender, @Addr, Sizeof(Addr)) <> 0 then
begin
ShowMessage('绑定出错');
end;
if iSender <> INVALID_SOCKET then
begin
if CreateIoCompletionPort(iSender, iHandle, 0, 0) <> 0 then
begin
tWorkThread.Create;
end;
end;
end;{ tWorkThread }constructor tWorkThread.Create;
begin
inherited Create(True);
FreeOnTerminate := true;
Resume;
end;procedure tWorkThread.Execute;
var
HandleData: PPerHandleData;
byteRece, Key: DWORD;
OperPosted: boolean;
errCode: integer;
begin
while not Terminated do
begin
if not GetQueuedCompletionStatus(iHandle, byteRece, Key, POverlapped(HandleData), INFINITE) then
begin
errCode:= GetLastError;
if errCode = 6 then
Terminate;
Continue;
end
else
begin
GlobalLock.Enter;
case HandleData.Statu of
ssRecv:
begin
ShowMessage('Recv');
end;
ssSend:
begin
ShowMessage('Send');
end;
end;
GlobalLock.Leave;
end; end;
end;procedure TForm1.FormCreate(Sender: TObject);
var
wsaData: TWSAData;
begin
WSAStartup(makeword(2, 0), wsaData);
end;procedure TForm1.FormDestroy(Sender: TObject);
begin
WSACleanup;
end;initialization
GlobalLock := TCriticalSection.Create;
finalization
GlobalLock.Free;end.Client端:
procedure TForm1.FormCreate(Sender: TObject);
var
wsaData: TWSAData;
begin
WSAStartup(makeword(2, 0), wsaData);
end;procedure TForm1.FormDestroy(Sender: TObject);
begin
WSAcleanup;
end;procedure TForm1.Button1Click(Sender: TObject);
var
addrin: TSockAddr;
tmpPacket: array [0..8191] of byte;
begin
iSender:= Socket(AF_INET, SOCK_DGRAM, 0);
addrin.sin_family:= AF_INET;
addrin.sin_port:= htons(4540);
addrin.sin_addr.S_addr:= inet_addr('127.0.0.1');
if Bind(iSender, @addrin, sizeof(addrin)) <> 0 then
ShowMessage('绑定出错')
else
begin
Sendto(iSender, tmpPacket, 8192, 0, addrin, sizeof(addrin));
end;
end;
解决方案 »
- ●●●●为了自己方便,也为大家方便,建立了一个DELPHI程序员QQ群:8194759●●●●
- 在关闭form时提示保存数据,在那个事件中写代码?
- 读版本号BCB下错误,delphi正常(分不够再加)
- 请问我用的是SUIPACK 4 控件,当编译时,总是提示要我去注册,可是去了它的网站有找不到注册项,怎么办?
- 初学:timer为何不执行?
- Dbgrid的问题!急,在线等!
- 问一个很菜很菜的问题
- 一个查询的小问题,怎么在dbgrid中显示
- 汇编:远线程调用完一个目标线程的call后,想取此时eax里的值 delphi 怎么写?
- 谁知道这个错误是什么意思:Invalid BLOB handle in record buffer
- 这么写为什么不行?
- 关于解析字符串的的一个难题!(我想了半天也没弄出来,急求答案!!!)
const
BUFFER_SIZE = 4096;type
YServerAction = ( saSend, saRecv, saClose, saSendAndClose, saBroadcast );
//
//扩展的WSAOVERLAPPED,即"Overlapped"(单句柄数据)
//
YPerOverlappedEx = record
Overlap : WSAOVERLAPPED;
DataInf : WSABUF;
Buf : Array [0..BUFFER_SIZE-1] of Char;
Action : YServerAction;
end;
PPerOverlappedEx = ^YPerOverlappedEx; YWorkThread = class(TThread)
private
FCompletPort : THandle;
protected
procedure Execute; override;
end;var
Form1: TForm1;
iocp : THandle;
sock : TSocket;
workthread : YWorkThread;implementation{$R *.dfm}
procedure YWorkThread.Execute;
var
dwTransferd : DWORD;
pOverlapEx : PPerOverlappedEx;
sock : TSocket;
dwTransfer, dwFlag : DWORD;
begin
while (not Terminated) do
begin
dwTransferd := 0;
GetQueuedCompletionStatus( FCompletPort, dwTransferd, DWORD(sock),
POVERLAPPED(pOverlapEx), 1000 ); if ( dwTransferd = 0 ) then
begin
if ( Sock = 0 ) or ( pOverlapEx = nil ) then
continue;
end; case pOverlapEx^.Action of
saRecv : //完成了接收数据任务(pOverlapEx内有接收到的数据)
begin
messagebox(0,'recved','iocp',mb_ok); fillChar( pOverlapEx^.Overlap, sizeof(WSAOVERLAPPED), 0 );
FillChar( pOverlapEx^.Buf[0], BUFFER_SIZE, 0 );
pOverlapEx^.DataInf.len := BUFFER_SIZE;
pOverlapEx^.DataInf.buf := pOverlapEx^.Buf;
pOverlapEx^.Action := saRecv;
dwFlag := 0;
WSARecv( sock, @(pOverlapEx^.DataInf), 1, dwTransfer, dwFlag,
@(pOverlapEx^.Overlap), nil );
end; saSend : ;//完成了发送数据任务
end; //case pOverlapEx^.Action of
end; //while not terminated
end;procedure TForm1.FormCreate(Sender: TObject);
var
wsa : TWSAData;
begin
WSAStartup( $0202, wsa );
ListBox1.Font.Name := 'Courier New';
ListBox1.Font.Size := 9;
end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
WSACleanup;
end;procedure TForm1.Button1Click(Sender: TObject);
var
Addr: TSockAddr;
pOverlapEx : PPerOverlappedEx;
dwTransfer, dwFlag : DWORD;
begin
//先创建完成端口
iocp := CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0); //再创建线程
WorkThread := YWorkThread.Create( true );
WorkThread.FCompletPort := iocp;
WorkThread.FreeOnTerminate := true;
WorkThread.Resume; //再创建socket
sock := Socket( AF_INET, SOCK_DGRAM, 0 );
Addr.sin_family:= AF_INET;
Addr.sin_port:= htons(4545);
Addr.sin_addr.S_addr:= inet_addr('192.168.1.12'); if Bind( sock, @Addr, Sizeof(Addr) ) <> 0 then
begin
ShowMessage('绑定出错');
closehandle( iocp );
Exit;
end; //然后把socket和iocp绑定
CreateIoCompletionPort( sock, iocp, sock, 0 ); //最后,要投递一个recv请求
New( pOverlapEx );
fillChar( pOverlapEx^.Overlap, sizeof(WSAOVERLAPPED), 0 );
FillChar( pOverlapEx^.Buf[0], BUFFER_SIZE, 0 );
pOverlapEx^.DataInf.len := BUFFER_SIZE;
pOverlapEx^.DataInf.buf := pOverlapEx^.Buf;
pOverlapEx^.Action := saRecv; dwFlag := 0;
WSARecv( sock, @(pOverlapEx^.DataInf), 1, dwTransfer, dwFlag,
@(pOverlapEx^.Overlap), nil );
end;end.
len := sizeof(addr);
fillchar(addr,len,0);
WSARecvfrom( sock, @(pOverlapEx^.DataInf), 1, dwTransfer, dwFlag,
@addr,@len, @(pOverlapEx^.Overlap), nil );