2011-05-21 21 views
3

我在WinSock 2中編寫了一些TCP服務器,並且我收到了FD_READ事件的程序。在這個過程中,我需要解析收到的消息。該代碼是在這裏:PChar在StrPLCopy上無效的指針操作

procedure TfrmMain.WndProc_OnWSANetEvent(var Msg: TMessage); 
Var 
    iCurrThread, n : Integer; 
    i : Integer; 
    temp : PChar; 
    len : Integer; 
    params : PChar; 
    username : PChar; password : PChar; 
    ind : Integer; 
    tempy : PChar; 
    tempn : PChar; 
begin 
    case WSAGetSelectEvent(Msg.LParam) of 
    FD_READ : 
     while True do 
     begin 
     if (FreeRThreads.GetCount <> 0) then 
      begin 
      iCurrThread := FreeRThreads.Pop; 
      if (ReadThreads[iCurrThread].Terminated) then 
       begin 
       ReadThreads[iCurrThread].SetFSocket(Msg.WParam); 
       ReadThreads[iCurrThread].Execute; 

       temp := ReadThreads[iCurrThread].GetFText; 
       meLog.Lines.Add(temp); 

       if (copy(temp,1,2)='AU') then 
        begin 
        StrPLCopy(params, PChar(copy(temp, 7, StrToInt(copy(temp, 3, 4)))), 16372); 
        ind := pos(' ', params); 
        StrPLCopy(username, PChar(copy(params, 1, ind-1)), 16372); 
        StrPLCopy(password, PChar(copy(params, ind + 1, StrLen(params))), 16372); 

        StrPLCopy(tempy, PChar('AU0001y'), 14); 
        StrPLCopy(tempn, PChar('AU0001n'), 14); 

        if (username=PChar('dizpers')) then 
         if (password=PChar('admin')) then 
         send(Msg.WParam, tempy^, 14, 0) 
         else 
         send(Msg.WParam, tempn^, 14, 0) 
        else 
         send(Msg.WParam, tempn^, 14, 0); 

        meLog.Lines.Add('USER = '+username); 
        meLog.Lines.Add('PASSWORD = '+password); 
        end; 



       FreeRThreads.Push(iCurrThread); 
       break; 
       end; 
      end; 
     end; 
    FD_CLOSE : 
     begin 
     n := CSocketsCount - 1; 
     for i := 0 to n do 
      if (ClientSockets[i] = Msg.WParam) then 
      begin 
       closesocket(ClientSockets[i]); 
       FreeSockets.Push(i); 
       break; 
      end; 
     end; 
    end; 
end; 

在調試我有一個「ACCES衝突...地址寫......」上線

StrPLCopy(params, PChar(copy(temp, 7, StrToInt(copy(temp, 3, 4)))), 16372); 

PLZ,幫我解決了這個問題,並瞭解爲什麼發生了。 TIA!

+1

任何理由,你爲什麼沒有去像Indy(或其他)一樣設置TCP組件? – Misha 2011-05-22 01:13:23

回答

4

必須爲params變量分配內存使用StrPLCopy之前(這同樣適用usernamepasswordtempytempn

檢查該樣本

Var 
    Dest : PChar; 
    Source : PChar; 
begin 
    Source:='This is a buffer to copy'; 
    //alloc a buffer of 1024 bytes 
    GetMem(Dest,1024); 
    try 
     //copy 
     StrPLCopy(Dest, Source, Length(Source)); 
     //do something 
     Writeln(Dest); 
    finally 
     //free the memory 
     FreeMem(Dest); 
    end; 
end; 
+0

+1,這樣第一個答案就會在最上面。 – 2011-05-21 17:55:29

+0

Thx!示例工作正常。但現在我有另一個問題。我知道我需要分配的內存大小,但是我知道其他PChar變量只知道它們的長度最多應該是16372.因此,如果我不知道大小,我可以爲變量獲取內存? – dizpers 2011-05-21 18:07:57

+3

@dizpers請問,作爲一個新的問題,一些更多的細節 – 2011-05-21 18:22:38