。。。。。。。。。。。。 (0分)

  • 主题发起人 主题发起人 陈一蛟
  • 开始时间 开始时间
你如果用过SPI方面的开发, 就应该知道不论是WSARecv还是Recv他们对应的SPI函数
都是对应WSPSend,只要导出这个函数可以截获发送请求,从这个地方可以看出不论是recv还是WSARecv都是调用的相同函数,只是recv设置了一些默认参数而已.
其实很多API函数本身是通过其他API函数组合而成的,比如在NT/2000/XP下基本上所有的
ANSI的字符类的函数都是内部用宽字符串版本实现的.
 
....................
 
......................
 
......................
 

To bluely:
既然你要测试,那我改一下服务器引擎,把有状态改为无状态,改好后给你测试,告诉我你的邮件地址。

 
..................
 

客户端测试代码:

unit ConnMain;

interface

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

type
TThreadConnections = class(TThread)
private
FRemoteAddress: string;
FRemotePort: string;
FClientSocket: TTcpClient;
protected
procedure Execute; override;
procedure AddResult;
public
iCount: integer;
FRecvStr: string;
constructor Create(CreateSuspended: Boolean; Address, Port: string);
destructor Destroy; override;
end;

TForm1 = class(TForm)
Label3: TLabel;
edtThreads: TEdit;
Memo1: TMemo;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Label1: TLabel;
edtAddress: TEdit;
Label2: TLabel;
edtPort: TEdit;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
ThreadPools: TList;
Conn: TThreadConnections;
public
{ Public declarations }
procedure AddResult(RecvStr: string);
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

constructor TThreadConnections.Create(CreateSuspended: Boolean; Address, Port: string);
begin
FreeOnTerminate := True;
FRemoteAddress := Address;
FRemotePort := Port;
iCount := 0;
inherited Create(CreateSuspended);
end;

destructor TThreadConnections.Destroy;
begin
inherited Destroy;
end;

procedure TThreadConnections.Execute;
begin
try
while not Terminated do
begin
if not Assigned(FClientSocket) then
begin
FClientSocket := TTcpClient.Create(nil);
FClientSocket.RemotePort := FRemotePort;
FClientSocket.RemoteHost := FRemoteAddress;
FClientSocket.Open;
FRecvStr := FClientSocket.Receiveln;
Synchronize(AddResult);
Inc(iCount);
end else
if FClientSocket.Connected then
begin
FClientSocket.Sendln(IntToStr(ThreadID) + ' : Open:' + IntToStr(iCount));
FRecvStr := FClientSocket.Receiveln;
Synchronize(AddResult);
if FClientSocket <> nil then
FClientSocket.Close;
FreeAndNil(FClientSocket);
sleep(40);
end
end;
except
raise ;
end;
end;

procedure TThreadConnections.AddResult;
begin
Form1.AddResult(FRecvStr);
end;

procedure TForm1.AddResult(RecvStr: string);
begin
Memo1.Lines.Add(RecvStr);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
i, iThreads: integer;
Address, Port: string;
begin
iThreads := StrToInt(edtThreads.Text);
Address := Trim(edtAddress.Text);
Port := Trim(edtPort.Text);
for i := 1 to iThreads do
begin
Conn := TThreadConnections.Create(True, Address, Port);
ThreadPools.Add(Conn);
end;
for i := 0 to ThreadPools.Count - 1 do
TThreadConnections(ThreadPools).Resume;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
try
while ThreadPools.Count > 0 do
begin
if Assigned(ThreadPools[0]) then
begin
if TThreadConnections(ThreadPools[0]).Suspended then
TThreadConnections(ThreadPools[0]).Resume;
Memo1.Lines.Add(IntToStr(TThreadConnections(ThreadPools[0]).ThreadID) +
' : ' + IntToStr(TThreadConnections(ThreadPools[0]).iCount));
TThreadConnections(ThreadPools[0]).Terminate;
end;
ThreadPools.Delete(0);
end;
except
ThreadPools.Clear;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
ThreadPools := TList.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
FreeAndNil(ThreadPools);
end;

end.

 

服务器 Demo 已经发送

1、客户端连接,服务器发送问候语句(以 #13#10 字符结尾)
2、客户端发送命令(任意字符,要以 #13#10 字符结尾)
3、服务器回应命令请求(以 #13#10 字符结尾),(在无状态模式下,服务器将会断开客户端连接)




 

》》》我前天阻塞模式的压力测试,测试啦两个多小时,开啦四个客户端进程,每个进程有4个连接线程,服务器端运行啦 10 个线程的线程池,在两个小时内响应啦 3 百 50 多万次的并发请求服务。服务器在这两个小时内终于没有出现任何问题(写啦两个多月,阻塞到非阻塞,后又从非阻塞从新转成阻塞模式,最后两个星期就只写啦三百多行代码)。

======》上面说得测试就是使用这个服务器和已经贴出来的客户端代码

 
..................
 

哦, 请老兄把你的 Server 和 Client 程序发过来,我测试一下,请勿推辞哦

c1005@263.net

 
to bluely:
请把你的测试程序发过来给我看看,或者可以把代码贴出来,
 
接受答案了.
 
后退
顶部