程序比较长,不方便全贴出来。但是跟踪到这个过程的 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;

解决方案 »

  1.   

    GetMem(NewContent, SendLength);//改为这个试一下
    NewContent:=allocmem(SendLength);
      

  2.   

    谢谢大家关心啦,不过问题还没解决,
    (在我添加 //************** 之间的那些信息之前,发送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;
      

  3.   

    我把 GetMem 和 FreeMem 换为 SysGetMem 和 SysFreeMem 后, 这下好了, 
    在 ServerRead 结束之后, 导致无效页错误被系统关闭. 由于基础不扎实,
    看不懂汇编, 只知道在一个 ret $0100 的语句执行了就完蛋了... 
    那位好心人拉我一把吧!