{--------------------------------------------------------------
Simple Example.
Implement TCP(both Client and Server) with Socket API
<zw84611@sina.com>
--------------------------------------------------------------}
if (CliSocket = INVALID_SOCKET)or(SvrSocket = INVALID_SOCKET) then
begin
ShowMessage(inttostr(WSAGetLastError())+' Socket创建失败');
CloseSocket(CliSocket);
exit;
end;
err := Listen(SvrSocket,5);
if err<>0 then ShowMessage('Listen error.');
{optval := 1;
if SetSockopt(SvrSocket,SOL_SOCKET,SO_REUSEADDR,pchar(@optval),sizeof(optval)) = SOCKET_ERROR then
begin
showmessage('SO_REUSEADDR set error.');
end; }
//绑定消息映射
WSAAsyncSelect(SvrSocket, Handle , WM_SOCK, FD_READ or FD_ACCEPT or FD_CONNECT or FD_WRITE or FD_CLOSE);
WSAAsyncSelect(CliSocket, Handle , WM_SOCK, FD_READ or FD_ACCEPT or FD_CONNECT or FD_WRITE or FD_CLOSE);
end;
procedure TForm1.SockConnect;
var
err: integer;
begin
CliAddrIn.sin_addr.s_addr:=inet_addr(PChar(Edit1.Text));
CliAddrIn.sin_family := AF_INET;
CliAddrIn.sin_port :=htons(TCP_PORT);
repeat
err:=connect(CliSocket,CliAddrIn, SizeOf(CliAddrIn));
if err = -1 then
begin
{ if we use WSAAsyncSelect(CliSocket...) in order to receive data at
Client side, here will get error, but it still works. why?
}
//ShowMessage('connect error.');
//ListBox1.Items.Add('connect error.');
HasConnected := false;
break;
end
else
begin
HasConnected := true;
IsServer := false;
end;
until err=0;
end;
procedure TForm1.SendData(Content: string);
begin
Send(CliSocket,Content[1],length(Content),0);
end;
procedure TForm1.ReadData(var Message: TMessage);
var
Event: word;
Buf:array[0..1023] of char;
AddrLen, DataLen: integer;
begin
//
AddrLen := sizeof(SvrAddrIn);
Event := WSAGetSelectEvent(Message.LParam);
//FillChar(SvrAddrIn,AddrLen,0);
case Event of
FD_CONNECT:
begin
ListBox1.Items.Add('connect');
HasConnected := true;
//do nothing?
end;
FD_ACCEPT:
begin
IsServer := true;
HasConnected := true;
ListBox1.Items.Add('accept');
//CloseSocket(CliSocket);
CliSocket := Accept(SvrSocket,@SvrAddrIn,@AddrLen);
ListBox1.Items.Add(format(' port:%d, addr:%s',[SvrAddrIn.sin_port,
inet_ntoa(SvrAddrIn.sin_addr)]));
end;
FD_READ:
begin
DataLen := Recv(CliSocket,Buf,1024,0);
buf[DataLen] := #0;
ListBox1.Items.Add(Buf);
{DataLen := RecvFrom(CliSocket,Buf,sizeof(buf),0,CliAddrIn,AddrLen);
ListBox1.Items.Add(format(' port:%d, addr:%s',[CliAddrIn.sin_port,
inet_ntoa(CliAddrIn.sin_addr)])+strpas(buf));}
end;
FD_WRITE:
begin
ListBox1.Items.Add('write');
end;
FD_OOB:
begin
ListBox1.Items.Add('FD_OOB');
end;
FD_CLOSE:
begin
HasConnected := false;
ListBox1.Items.Add('close');
end;
end; //end of case
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
//202.104.32.230
if (not IsServer)and(not HasConnected) then SockConnect;
SendData('hello, world');
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
CloseSocket(SvrSocket);
CloseSocket(CliSocket);
end;