程序比较长,不方便全贴出来。但是跟踪到这个过程的 GetMem 行时出错(访问非法内存),各位帮我看看,是不是这里出问题了?如果认为错误不在这段代码,需要全部代码,请留下油箱。或者给我发邮件([email protected])procedure TfmSrvMain.ServerSend(ASocket: TCustomWinSocket;
Cmd: Byte; Content: PChar; ContentLength: Integer);
var
NewContent: PChar;
SendLength: Integer;
begin
SendLength := ContentLength + SizeOf(Cmd);
GetMem(NewContent, SendLength);
try
NewContent[0] := Chr(Cmd);
System.Move(Content^, NewContent[1], ContentLength);
ASocket.SendBuf(NewContent^, SendLength);
finally
FreeMem(NewContent, SendLength);
end;
end;
Cmd: Byte; Content: PChar; ContentLength: Integer);
var
NewContent: PChar;
SendLength: Integer;
begin
SendLength := ContentLength + SizeOf(Cmd);
GetMem(NewContent, SendLength);
try
NewContent[0] := Chr(Cmd);
System.Move(Content^, NewContent[1], ContentLength);
ASocket.SendBuf(NewContent^, SendLength);
finally
FreeMem(NewContent, SendLength);
end;
end;
NewContent:=allocmem(SendLength);
(在我添加 //************** 之间的那些信息之前,发送8k的文件也行),现在把出问题可能相关的块列出来,这样大家或许能看得更清楚一点:procedure TfmSrvMain.ServerFileDownAnswer(ASocket: TCustomWinSocket;
Buffer: string);
{ File download request content: 'filename' + position }
{ Answer content: 'filename:' + size + FileEndFlag + FileContent }
{ FileEndFlag: 55: False, AA: True }
var
SendLen, DownLoadPos, fsize, offset: Integer;
Buf: PChar;
Del, FileEndFlag: Char;
begin
FServerState := ssFive;
{...}
CopyMemory(@DownLoadPos, PChar(Buffer), SizeOf(DownLoadPos));
Delete(Buffer, 1, 4); with TFileStream.Create(Buffer, fmOpenRead) do
try
//*************
fsize := Size;
Del := ':';
FileEndFlag := Chr($55);
offset := 0;
SendLen := Length(Buffer) + SizeOf(fsize) + SizeOf(FileEndFlag) + fsize; GetMem(Buf, SendLen);
CopyMemory(Buf, @Buffer[1], Length(Buffer)); // filename
Inc(offset, Length(Buffer));
CopyMemory(@Buf[offset], @Del, SizeOf(Char)); // Delimeter ':'
Inc(offset);
CopyMemory(@Buf[offset], @fsize, SizeOf(Integer)); // file size
Inc(offset, SizeOf(Integer));
//**************
try
Position := DownLoadPos;
if Read(Buf[offset + 1], fsize) <= fsize then // When size too big to send...
FileEndFlag := Chr($AA); CopyMemory(@Buf[offset], @FileEndFlag, SizeOf(Char)); // file end flag(55 or AA)
ServerSend(ASocket, S_FILEDOWN_ACK, Buf, SendLen);
finally
FreeMem(Buf);
end;
finally
Free;
end;
end;
procedure TfmSrvMain.ServerRead(ASocket: TCustomWinSocket);
var
Buf: string;
Cmd: Byte;
begin
Buf := ASocket.ReceiveText;
CopyMemory(@Cmd, PChar(Buf), SizeOf(Cmd));
Delete(Buf, 1, 1); case Cmd of
C_LOGIN_REQ: ServerCheckLogin(ASocket, Buf);
C_FILELIST_REQ: ServerFileListAnswer(ASocket);
C_MESSAGE_REQ: ServerMessageAnswer(ASocket);
C_LOGOFF_REQ: ServerLogoffAnswer(ASocket);
C_FILEDOWN_REQ: ServerFileDownAnswer(ASocket, Buf);
C_FILEUP_REQ: ServerFileUpAnswer(ASocket);
end;
end;procedure TfmSrvMain.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
begin
ServerRead(Socket);
end;
在 ServerRead 结束之后, 导致无效页错误被系统关闭. 由于基础不扎实,
看不懂汇编, 只知道在一个 ret $0100 的语句执行了就完蛋了...
那位好心人拉我一把吧!