Microsoft Platform SDK当中有一个有一个测试的客户端,每个进程允许64个线程,每个线程一个连接,使用ECHO(回显,即收到什么再回发给客户端)。当初我就是用这个测试的,当然也可以在其中进一步完善成你所需要的,只是多开几个程序就好了。
如果你只是为了测试连接数的话...unit TestMain;interfaceuses winsock2,Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls, Spin,Network_Utils;type TfrmMain = class(TForm) edtAddress: TEdit; edtPort: TEdit; btnDisconn: TButton; btnConnect: TButton; lblAddr: TLabel; lblPort: TLabel; seIncConns: TSpinEdit; lblConnect: TLabel; lblConns: TLabel; stConns: TStaticText; Timer1: TTimer; procedure btnConnectClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure btnDisconnClick(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); private { Private declarations } SocketList:TList; Connecting:Boolean; public { Public declarations } end;var frmMain: TfrmMain;implementation{$R *.dfm} procedure TfrmMain.btnDisconnClick(Sender: TObject); var I: Integer; sd:TSocket; begin if Not Assigned(SocketList) then Exit; if Connecting then Exit; Connecting:=true; btnDisconn.Enabled:=false; try for I :=SocketList.Count downto 1 do begin Sd:=TSocket(SocketList.Items[I-1]); SocketList.Delete(I-1); CloseSocket(sd); Application.ProcessMessages; end; finally Connecting:=false; btnDisconn.Enabled:=true; end; end;procedure TfrmMain.btnConnectClick(Sender: TObject); var I:Integer; sd:TSocket; Port:Integer; begin btnConnect.Enabled:=false; if Connecting then Exit; Connecting:=true; edtAddress.Enabled:=false; edtPort.Enabled:=false; seIncConns.Enabled:=false; try if Not Assigned(SocketList) then Exit; Port:=StrToIntDef(edtPort.Text,0); if Port=0 then Exit; for I := 0 to seIncConns.Value - 1 do begin Application.ProcessMessages; Sd:=ClientConnect(edtAddress.Text,Port(*,false*)); if SD=INVALID_SOCKET then break; SocketList.Add(Pointer(Sd)); end; finally Connecting:=false; edtAddress.Enabled:=true; edtPort.Enabled:=true; seIncConns.Enabled:=true; btnConnect.Enabled:=true; end; end;procedure TfrmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin CanClose:=Not Connecting;
end;procedure TfrmMain.FormCreate(Sender: TObject); var WSAData:TWSADATA; begin Connecting:=false; WSAStartup(WINSOCK_VERSION,WSAData); try SocketList:=TList.Create; except SocketList:=nil; end;end;procedure TfrmMain.FormDestroy(Sender: TObject); begin btnDisConn.Click; if Assigned(SocketList) then SocketList.Free; WSACleanup; end;procedure TfrmMain.Timer1Timer(Sender: TObject); var I,iSize:Integer; sd:TSocket; CheckVal:DWORD; begin if Not Assigned(SocketList) then Exit; Timer1.Enabled:=false; try if Not Connecting then for I :=SocketList.Count downto 1 do begin Sd:=TSocket(SocketList.Items[I-1]); iSize:=sizeof(DWORD); if getsockopt( sd, SOL_SOCKET, $700C(*SO_CONNECT_TIME*), PChar(@CheckVal), iSize)=SOCKET_ERROR then begin begin SocketList.Delete(I-1); CloseSocket(sd); continue; end; end; {iSize:=sizeof(DWORD); if getsockopt( sd, SOL_SOCKET, SO_ERROR, PChar(@CheckVal), iSize)<0 then begin if WSAGetLastError=WSAENOTSOCK then begin SocketList.Delete(I-1); CloseSocket(sd); continue; end; end;} end; finally stConns.Caption:=IntTOStr(SocketList.Count); Timer1.Enabled:=true; end; end;end. 最高可以连接六万多...
unit Network_Utils;interface uses Classes , Winsock2 , Windows , SysUtils; type function IsIP(const AHost: String): Boolean; function LocalGetHostByName(const AHost: String): String; function ResolveHost(const AHost: String):String; function ClientConnect( Address: String ; Port: Integer ; Blocking: Boolean = true ; TIMEOUT: LongInt = 30(*sec*) ): TSocket; function CheckIsValidSock(Sd: TSocket): BOOL; implementation//Test if AHost is a valid IP address string //检查一个串是否为合法的IP地址串 procedure WriteLog( const s: string); begin end;function IsIP(const AHost:String):Boolean; var iLen , I , TestDigit , DotCount: Integer; TestIP: String; begin Result := false; TestIP := AHost + '.'; iLen := Length(AHost); if(iLen<7) or (iLen>15) then Exit; TestDigit := 0; DotCount := 0; for i := 1 to iLen + 1 do begin if(((TestIP[i] < '0') or (TestIP[i] > '9')) and ((TestIP[i] <> '.') or (i = 0))) then Exit; if(TestIP[i] = '.') then begin if (TestDigit > 255) or (TestDigit < 0) then Exit; if(TestIP[i-1] = '.') then Exit; TestDigit := 0; Inc(DotCount); end else TestDigit := TestDigit * 10 + (ord(TestIP[i]) - 48); end; Result := DotCount = 4; end;function LocalGetHostByName(const AHost:String):String; var WSAData: TWSADATA; Host: PHostEnt; begin Result := AHost; if(WSAStartup(WINSOCK_VERSION, WSAData) <> 0) then Exit; try Host := gethostbyname(PChar(AHost)); Result := IntToStr(Byte(Host^.h_addr_list^[0])) + '.' + IntToStr(Byte(Host^.h_addr_list^[1])) + '.' + IntToStr(Byte(Host^.h_addr_list^[2])) + '.' + IntToStr(Byte(Host^.h_addr_list^[3])); if Not IsIP(Result) then Result:=AHost; finally WSACleanup; end; end;function ResolveHost(const AHost: String): String; begin Result := AHost; if AnsiSameText(AHost, 'LOCALHOST') or AnsiSameText(AHost, '(Local)') or AnsiSameText(AHost, '.') then // this computer Result := '127.0.0.1' else if Not IsIP(Result) then Result := LocalGetHostByName(AHost); end;function ConnectServer( Sd: TSocket ; Address: String ; Port: Integer ): Boolean; var sa: TSockAddr; begin Result := false; FillChar(sa, sizeof(TSockAddr), 0); sa.sin_family := AF_INET; sa.sin_port := htons(Port); Address := ResolveHost(Address); sa.sin_addr.S_addr := inet_addr(PChar(Address)); if Connect(Sd, @sa, sizeof(TSockAddr)) = SOCKET_ERROR then Exit; Result:=true; end; function ClientConnect( Address: String ; Port: Integer ; Blocking: Boolean ; TIMEOUT: LongInt ): TSocket; var Sd: TSocket; nNonBlocking: u_long; oTV: TTimeVal; oRead , oWrite: TFDSET; nResult , nError , nLen: Integer; begin Result := INVALID_SOCKET; Sd := CreateSocket(false); if Not Blocking then begin nNonBlocking := 1; if (ioctlsocket(Sd, FIONBIO, nNonBlocking) = SOCKET_ERROR) then begin Shutdown(sd, sd_both); CloseSocket(sd); Exit; end; oTV.tv_sec := TIMEOUT ; oTV.tv_usec := TIMEOUT * 1000; FD_ZERO(oRead); FD_ZERO(oWrite); if Not ConnectServer(Sd, Address, Port) then begin if WSAGetLastError <> WSAEWOULDBLOCK then begin Shutdown(sd,sd_both); CloseSocket(sd); Exit; end else // need select begin FD_SET(Sd, oRead); oWrite := oRead; nResult := select(Sd + 1, @oRead, @oWrite, nil, @oTV); if (nResult = 0) then begin Shutdown(sd, sd_both); CloseSocket(sd); Exit; end; if (FD_ISSET(SD, oRead) or FD_ISSET(SD, oWrite)) then begin nError := 0; nLen := sizeof(nError); if (getsockopt(Sd, SOL_SOCKET, SO_ERROR, PChar(nError), nLen) < 0) then begin Shutdown(sd, sd_both); CloseSocket(sd); Exit; end; end else begin Shutdown(sd, sd_both); CloseSocket(sd); Exit; end; end; end; Result := Sd; Exit; end;
if Not ConnectServer(Sd, Address, Port) then begin Shutdown(sd, sd_both); CloseSocket(sd); Exit; end; Result := sd; end; function CheckIsValidSock(Sd: TSocket): BOOL; var Connect_Time : integer; nSize : Integer; begin Result := False; try nSize := sizeof(Connect_Time); if getsockopt( Sd , SOL_SOCKET , $700C{SO_CONNECT_TIME} , @Connect_Time , nSize) = SOCKET_ERROR then if WSAENOTSOCK = WSAGetLastError then Exit; Except Exit; end; Result := True; end; end.
winsock2,Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, Spin,Network_Utils;type
TfrmMain = class(TForm)
edtAddress: TEdit;
edtPort: TEdit;
btnDisconn: TButton;
btnConnect: TButton;
lblAddr: TLabel;
lblPort: TLabel;
seIncConns: TSpinEdit;
lblConnect: TLabel;
lblConns: TLabel;
stConns: TStaticText;
Timer1: TTimer;
procedure btnConnectClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure btnDisconnClick(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
private
{ Private declarations }
SocketList:TList;
Connecting:Boolean;
public
{ Public declarations }
end;var
frmMain: TfrmMain;implementation{$R *.dfm}
procedure TfrmMain.btnDisconnClick(Sender: TObject);
var
I: Integer;
sd:TSocket;
begin
if Not Assigned(SocketList) then
Exit;
if Connecting then
Exit;
Connecting:=true;
btnDisconn.Enabled:=false;
try
for I :=SocketList.Count downto 1 do
begin
Sd:=TSocket(SocketList.Items[I-1]);
SocketList.Delete(I-1);
CloseSocket(sd);
Application.ProcessMessages;
end;
finally
Connecting:=false;
btnDisconn.Enabled:=true;
end;
end;procedure TfrmMain.btnConnectClick(Sender: TObject);
var
I:Integer;
sd:TSocket;
Port:Integer;
begin
btnConnect.Enabled:=false;
if Connecting then
Exit;
Connecting:=true;
edtAddress.Enabled:=false;
edtPort.Enabled:=false;
seIncConns.Enabled:=false;
try
if Not Assigned(SocketList) then
Exit;
Port:=StrToIntDef(edtPort.Text,0);
if Port=0 then
Exit; for I := 0 to seIncConns.Value - 1 do
begin
Application.ProcessMessages;
Sd:=ClientConnect(edtAddress.Text,Port(*,false*));
if SD=INVALID_SOCKET then
break;
SocketList.Add(Pointer(Sd)); end;
finally
Connecting:=false;
edtAddress.Enabled:=true;
edtPort.Enabled:=true;
seIncConns.Enabled:=true;
btnConnect.Enabled:=true; end;
end;procedure TfrmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
CanClose:=Not Connecting;
end;procedure TfrmMain.FormCreate(Sender: TObject);
var
WSAData:TWSADATA;
begin
Connecting:=false;
WSAStartup(WINSOCK_VERSION,WSAData);
try
SocketList:=TList.Create;
except
SocketList:=nil;
end;end;procedure TfrmMain.FormDestroy(Sender: TObject);
begin
btnDisConn.Click;
if Assigned(SocketList) then
SocketList.Free;
WSACleanup;
end;procedure TfrmMain.Timer1Timer(Sender: TObject);
var
I,iSize:Integer;
sd:TSocket;
CheckVal:DWORD;
begin
if Not Assigned(SocketList) then
Exit;
Timer1.Enabled:=false;
try
if Not Connecting then for I :=SocketList.Count downto 1 do
begin
Sd:=TSocket(SocketList.Items[I-1]);
iSize:=sizeof(DWORD);
if getsockopt( sd,
SOL_SOCKET,
$700C(*SO_CONNECT_TIME*),
PChar(@CheckVal),
iSize)=SOCKET_ERROR then
begin
begin
SocketList.Delete(I-1);
CloseSocket(sd);
continue;
end;
end;
{iSize:=sizeof(DWORD);
if getsockopt( sd,
SOL_SOCKET,
SO_ERROR,
PChar(@CheckVal),
iSize)<0 then
begin
if WSAGetLastError=WSAENOTSOCK then
begin
SocketList.Delete(I-1);
CloseSocket(sd);
continue;
end;
end;} end;
finally
stConns.Caption:=IntTOStr(SocketList.Count);
Timer1.Enabled:=true;
end;
end;end.
最高可以连接六万多...
uses
Classes
, Winsock2
, Windows
, SysUtils;
type
function IsIP(const AHost: String): Boolean;
function LocalGetHostByName(const AHost: String): String;
function ResolveHost(const AHost: String):String;
function ClientConnect( Address: String
; Port: Integer
; Blocking: Boolean = true
; TIMEOUT: LongInt = 30(*sec*)
): TSocket;
function CheckIsValidSock(Sd: TSocket): BOOL;
implementation//Test if AHost is a valid IP address string
//检查一个串是否为合法的IP地址串
procedure WriteLog( const s: string);
begin
end;function IsIP(const AHost:String):Boolean;
var
iLen
, I
, TestDigit
, DotCount: Integer;
TestIP: String;
begin
Result := false;
TestIP := AHost + '.';
iLen := Length(AHost);
if(iLen<7) or (iLen>15) then Exit;
TestDigit := 0;
DotCount := 0;
for i := 1 to iLen + 1 do
begin
if(((TestIP[i] < '0') or (TestIP[i] > '9')) and ((TestIP[i] <> '.') or (i = 0))) then Exit;
if(TestIP[i] = '.') then
begin
if (TestDigit > 255) or (TestDigit < 0) then Exit;
if(TestIP[i-1] = '.') then Exit;
TestDigit := 0;
Inc(DotCount);
end
else
TestDigit := TestDigit * 10 + (ord(TestIP[i]) - 48);
end;
Result := DotCount = 4;
end;function LocalGetHostByName(const AHost:String):String;
var
WSAData: TWSADATA;
Host: PHostEnt;
begin
Result := AHost;
if(WSAStartup(WINSOCK_VERSION, WSAData) <> 0) then Exit;
try
Host := gethostbyname(PChar(AHost));
Result := IntToStr(Byte(Host^.h_addr_list^[0])) + '.' +
IntToStr(Byte(Host^.h_addr_list^[1])) + '.' +
IntToStr(Byte(Host^.h_addr_list^[2])) + '.' +
IntToStr(Byte(Host^.h_addr_list^[3]));
if Not IsIP(Result) then Result:=AHost;
finally
WSACleanup;
end;
end;function ResolveHost(const AHost: String): String;
begin
Result := AHost;
if AnsiSameText(AHost, 'LOCALHOST') or AnsiSameText(AHost, '(Local)') or AnsiSameText(AHost, '.') then // this computer
Result := '127.0.0.1'
else if Not IsIP(Result) then
Result := LocalGetHostByName(AHost);
end;function ConnectServer( Sd: TSocket
; Address: String
; Port: Integer
): Boolean;
var
sa: TSockAddr;
begin
Result := false;
FillChar(sa, sizeof(TSockAddr), 0);
sa.sin_family := AF_INET;
sa.sin_port := htons(Port);
Address := ResolveHost(Address);
sa.sin_addr.S_addr := inet_addr(PChar(Address));
if Connect(Sd, @sa, sizeof(TSockAddr)) = SOCKET_ERROR then Exit;
Result:=true;
end;
function ClientConnect( Address: String
; Port: Integer
; Blocking: Boolean
; TIMEOUT: LongInt
): TSocket;
var
Sd: TSocket;
nNonBlocking: u_long;
oTV: TTimeVal;
oRead
, oWrite: TFDSET;
nResult
, nError
, nLen: Integer;
begin
Result := INVALID_SOCKET;
Sd := CreateSocket(false);
if Not Blocking then
begin
nNonBlocking := 1;
if (ioctlsocket(Sd, FIONBIO, nNonBlocking) = SOCKET_ERROR) then
begin
Shutdown(sd, sd_both);
CloseSocket(sd);
Exit;
end; oTV.tv_sec := TIMEOUT ;
oTV.tv_usec := TIMEOUT * 1000;
FD_ZERO(oRead);
FD_ZERO(oWrite); if Not ConnectServer(Sd, Address, Port) then
begin
if WSAGetLastError <> WSAEWOULDBLOCK then
begin
Shutdown(sd,sd_both);
CloseSocket(sd);
Exit;
end
else // need select
begin
FD_SET(Sd, oRead);
oWrite := oRead;
nResult := select(Sd + 1, @oRead, @oWrite, nil, @oTV);
if (nResult = 0) then
begin
Shutdown(sd, sd_both);
CloseSocket(sd);
Exit;
end; if (FD_ISSET(SD, oRead) or FD_ISSET(SD, oWrite)) then
begin
nError := 0;
nLen := sizeof(nError);
if (getsockopt(Sd, SOL_SOCKET, SO_ERROR, PChar(nError), nLen) < 0) then
begin
Shutdown(sd, sd_both);
CloseSocket(sd);
Exit;
end;
end
else
begin
Shutdown(sd, sd_both);
CloseSocket(sd);
Exit;
end;
end;
end;
Result := Sd;
Exit;
end;
if Not ConnectServer(Sd, Address, Port) then
begin
Shutdown(sd, sd_both);
CloseSocket(sd);
Exit;
end;
Result := sd;
end;
function CheckIsValidSock(Sd: TSocket): BOOL;
var
Connect_Time : integer;
nSize : Integer;
begin
Result := False;
try
nSize := sizeof(Connect_Time);
if getsockopt( Sd
, SOL_SOCKET
, $700C{SO_CONNECT_TIME}
, @Connect_Time
, nSize) = SOCKET_ERROR then
if WSAENOTSOCK = WSAGetLastError then Exit;
Except
Exit;
end;
Result := True;
end;
end.
使用完成端口+线程池+ConnectEx...