我正在为我的定制战舰游戏制作一个Matchmaking服务器。我是网络编码的初学者,所以我很抱歉提前愚蠢的问题。 :P
现在更接近主题了。我使用默认的Delphi Server / Client Socket组件。我在公共部分(clients: array of TCustomWinSocket;
)声明了我的数组,然后在主帧启动时我将长度设置为零(setLength(clients, 0);
)。现在令我困惑的部分是:每当我尝试访问数组程序的任何元素时,都会引发访问冲突异常。我已经以任何已知的方式检查过,程序永远不会超过数组的长度。
以下是抛出异常的代码示例:
procedure Tmain.Button1Click(Sender: TObject);
var
i: integer;
begin
for i := 0 to length(clients) do begin
if assigned(clients[i]) then begin
showmessage(IntToStr(i));
showmessage(IntToStr(i) + ': ' + clients[i].RemoteAddress);
end;
end;
end;
另一个例子:
procedure Tmain.serverClientConnect(Sender: TObject; Socket: TCustomWinSocket);
begin
addLog('(' + Socket.RemoteAddress + ':' + IntToStr(Socket.RemotePort) + ') Клиент подключился');
if length(clients) <> 0 then begin
showmessage(IntToStr(length(clients)));
setLength(clients, length(clients) + 1);
showmessage(IntToStr(length(clients)));
clients[length(clients)] := Socket;
end
else if length(clients) = 0 then begin
showmessage(IntToStr(length(clients)));
clients[0] := Socket;
end;
end;
基本上,每次我使用这个数组时都会产生访问冲突。我无法得到它,我限制代码保持在数组长度,但它没有。或者,也许是我的愚蠢常常导致它?
任何方式,我都可以使用一些帮助。
提前致谢! :)
答案 0 :(得分:4)
你在这个循环中跑掉了数组的末尾。 Length(clients)
比最后一个索引高一个,因为动态数组的索引从零开始。您必须使用Length(clients) - 1
或High(clients)
作为循环的终止符。
procedure Tmain.Button1Click(Sender: TObject);
var
i: integer;
begin
for i := 0 to High(clients) do begin // or Length(clients) - 1
if assigned(clients[i]) then begin
showmessage(IntToStr(i));
showmessage(IntToStr(i) + ': ' + clients[i].RemoteAddress);
end;
end;
end;
您的第二个代码块中也有类似的错误,另外还有一个非常清楚的错误:
procedure Tmain.serverClientConnect(Sender: TObject; Socket: TCustomWinSocket);
begin
addLog('(' + Socket.RemoteAddress + ':' + IntToStr(Socket.RemotePort) + ') Клиент подключился');
if length(clients) <> 0 then begin
showmessage(IntToStr(length(clients))); // Need - 1 or High() here
setLength(clients, length(clients) + 1);
showmessage(IntToStr(length(clients))); // Need - 1 or High() here
clients[length(clients)] := Socket;
end
else if length(clients) = 0 then begin // Second problem starts here
showmessage(IntToStr(length(clients))); // See text below
clients[0] := Socket;
end;
end;
第二个错误是在clients[0]
时尝试分配给Length(clients) = 0
,因为它是无效索引。如果数组长度为零,则没有元素0,因为数组是空的 - 其中没有元素 - 不是单个元素;您不能为其中包含零元素的数组赋值。
整个块的正确代码是这样的 - 你不需要两个测试,测试长度= 0,或者跳过所有的箍:
procedure Tmain.ServerClientConnect(Sender: TObject; Socket; TCustomSocket);
begin
AddLog('Whatever you want to log.');
SetLength(clients, Length(clients) + 1);
Clients[High(Clients)] := Socket;
end;