所以我有这个应用程序验证用户可以登录的天气。
它由多个客户端(最多200个)和一个处理登录查询(包含用户名,PW和IP)的服务器组成。服务器检查用户存在的天气并发回答案。
TLoginQuery是一个记录。
procedure TLogin_Form.btnLoginClick(Sender: TObject);
var LoginQuery1: TLoginQuery;
begin
if not LoginSocket.Active then
begin
LoginSocket.Open;
end;
//Paketchen schnüren.
LoginQuery1.Name := ledtName.Text;
LoginQuery1.Passwort := ledtPasswort.Text;
LoginQuery1.IP := LoginSocket.Socket.LocalAddress;
//LoginQuery ín den Socket legen.
LoginSocket.Socket.SendBuf(LoginQuery1, SizeOf(LoginQuery1));
end;
服务器目前显示:
procedure TServer_Form.ServerSocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var LoginQuery: TLoginQuery;
uservalid: boolean;
begin
uservalid := false;
Socket.ReceiveBuf(LoginQuery, SizeOf(LoginQuery));
if CheckIfUserValid(LoginQuery) then
begin
uservalid := true;
ServerSocket.Socket.SendBuf(uservalid, SizeOf(uservalid));
end;
end;
现在的问题是: 服务器(通常应该是这样)是否为每个客户端创建不同的套接字连接?
我的假设:
ClientA发送他的登录数据并从服务器接收用户有效的布尔值(上面的代码)。当用户有效的布尔值被写入套接字连接时,会发生以下情况:在ClientA可以获得uservalid布尔值之前(应该是这样)ClientB已经登录,从套接字读取并获取(因为它不应该) uservalid boolean。
可以使用每个客户端一个套接字进行干预。正确?
答案 0 :(得分:2)
TServerSocket.OnClientRead的Socket:TCustomWinSocket参数表示您的一个客户端与服务器之间的一个连接。因此,当客户端Foo发送登录记录,并且调用TServer_Form.ServerSocketClientRead时,只需说
if CheckIfUserValid(LoginQuery) then
begin
uservalid := true;
Socket.SendBuf(uservalid, SizeOf(uservalid));
end;
您将把数据发送给正确的客户。
答案 1 :(得分:0)
通常,您的服务器套接字不会将其外发消息广播到所有连接的客户端。相反,它将选择一个特定的连接客户端来发送响应。将来自不同客户端的所有连接视为唯一。当然,他们可能有一些共同的设置,但它们是独特的连接。 (在数据库中,连接的主键是所有服务器IP,服务器端口,客户端IP,客户端端口的组合)
我没有使用过TServerSocket,但是IPWorks库通过使用在接收方和发送方都指定的连接ID来明确这一点。这样您就知道您正在读/写的数据将使用特定的连接,而数据来自/到达预期的客户端。