Q&A

  • TMemoryStream 문제 다시 올립니다.. T.T
많은 분들께서 도움을 주셨는데.. 이렇게 다시 질문 올립니다. T.T



다들 눈치 채셨으리라.. 생각 하는데.. 제가 작업하는것이..



TVideo 콤포넌트를 써서..

캡쳐 -> bmp -> jpg -> stream -> 소켓 -> 소켓 -> stream -> jpg -> image 로

뿌려주는.. 화상 관련 Job 인데요..





소켓으로 Stream을 받아서 처리하는 부분인데.

이미지를 받아 처리를 하는 부분입니다.



자꾸 문제가 되는 부분이...



Socket.ReceiveBuf(sData,TempSize); <= 받아서..



sData.Position := 0; <--- 이곳!



Jpeg.LoadFromStream(sData); <- 또는 이곳!!



에서 'Access violation at address ........' 에러가 뜹니다...



만약 sData.Position := 0; 코드를 지우면...

다음 코드인 Jpeg.LoadFromStream(sData); 이 코드에서 Access violation 에러가

뜹니다...



제가 추측을 할수 잇는건.. sdata:= TMemoryStream.Create; 가.. 제대로 처리가 안

되었다는 것뿐이...



어제 부터 자꾸 문제를 일으키네여...



제가 개념을 모르고 있는것 같기도 하고.. 혹은 잘못 판단 하고 있는것 같기도 합니다.



아래는 사용된 소스를 올렸습니다...



도대체 뭐가 문제 일까요!!???



정녕.. 신의 장난이 아니고서야...흑흑흑..



감사합니다.



참!! 한가지 재미있는것.1!!



하나의 폼에서 서버/클라이언트 소켓을 붙여두고 소켓으로 보내면 정상

적으로 나옵니다... 그래서 어플리케이션을 별도로, 즉 서버/ 클라이언트

를 따로 분리 해서.. 서버 모듈만 아래와 같이 코딩을 햇는데... 문제가

생깁니다. 그 무시무시한 'Access violation at address ........' 라구요..



==================================================================

소켓으로 전달된 데이터를 받는 ServerSocket Read 이벤트..

==================================================================



procedure TForm1.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket);

var

TempSize : Integer;

sData : TMemoryStream;

Jpeg : TJpegImage;



begin

Try

sData := TMemoryStream.Create;

jpeg := TJpegimage.Create;





TempSize := Socket.ReceiveLength();

Socket.ReceiveBuf(sData,TempSize);

sData.Position := 0 ;

Jpeg.LoadFromStream(sData);

If Jpeg.Empty then Exit;

Image.Picture.Assign(Jpeg);



finally

sData.Free;

jpeg.Free;



End;





end;

1  COMMENTS
  • Profile
    묻지마다쳐 2001.06.17 07:53
    Ziker wrote:

    > 많은 분들께서 도움을 주셨는데.. 이렇게 다시 질문 올립니다. T.T

    >

    > 다들 눈치 채셨으리라.. 생각 하는데.. 제가 작업하는것이..

    >

    > TVideo 콤포넌트를 써서..

    > 캡쳐 -> bmp -> jpg -> stream -> 소켓 -> 소켓 -> stream -> jpg -> image 로

    > 뿌려주는.. 화상 관련 Job 인데요..

    >

    >

    > 소켓으로 Stream을 받아서 처리하는 부분인데.

    > 이미지를 받아 처리를 하는 부분입니다.

    >

    > 자꾸 문제가 되는 부분이...

    >

    > Socket.ReceiveBuf(sData,TempSize); <= 받아서..

    >

    > sData.Position := 0; <--- 이곳!

    >

    > Jpeg.LoadFromStream(sData); <- 또는 이곳!!

    >

    > 에서 'Access violation at address ........' 에러가 뜹니다...

    >

    > 만약 sData.Position := 0; 코드를 지우면...

    > 다음 코드인 Jpeg.LoadFromStream(sData); 이 코드에서 Access violation 에러가

    > 뜹니다...

    >

    > 제가 추측을 할수 잇는건.. sdata:= TMemoryStream.Create; 가.. 제대로 처리가 안

    > 되었다는 것뿐이...

    >

    > 어제 부터 자꾸 문제를 일으키네여...

    >

    > 제가 개념을 모르고 있는것 같기도 하고.. 혹은 잘못 판단 하고 있는것 같기도 합니다.

    >

    > 아래는 사용된 소스를 올렸습니다...

    >

    > 도대체 뭐가 문제 일까요!!???

    >

    > 정녕.. 신의 장난이 아니고서야...흑흑흑..

    >

    > 감사합니다.

    >

    > 참!! 한가지 재미있는것.1!!

    >

    > 하나의 폼에서 서버/클라이언트 소켓을 붙여두고 소켓으로 보내면 정상

    > 적으로 나옵니다... 그래서 어플리케이션을 별도로, 즉 서버/ 클라이언트

    > 를 따로 분리 해서.. 서버 모듈만 아래와 같이 코딩을 햇는데... 문제가

    > 생깁니다. 그 무시무시한 'Access violation at address ........' 라구요..

    >

    > ==================================================================

    > 소켓으로 전달된 데이터를 받는 ServerSocket Read 이벤트..

    > ==================================================================

    >

    > procedure TForm1.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket);

    > var

    > TempSize : Integer;

    > sData : TMemoryStream;

    > Jpeg : TJpegImage;

    >

    > begin

    > Try

    > sData := TMemoryStream.Create;

    > jpeg := TJpegimage.Create;

    >

    >

    > TempSize := Socket.ReceiveLength();

    > Socket.ReceiveBuf(sData,TempSize);

    > sData.Position := 0 ;

    > Jpeg.LoadFromStream(sData);

    > If Jpeg.Empty then Exit;

    > Image.Picture.Assign(Jpeg);

    >

    > finally

    > sData.Free;

    > jpeg.Free;

    >

    > End;

    >

    >

    > end;



    저기 sData는 TMemoryStream형인데

    ReceiveBuf로 데이터를 받을려면

    PChar형의 변수로 받아야 할건데요

    또는 PByte형이나..

    객체로 걍 받으면 안되죠..





    될지 안될지 모르지만 이렇게 바꿔 보세요



    var

    TempSize : Integer;

    sData : PChar;

    Jpeg : TJpegImage;

    stream : TMemoryStream;

    begin

    TempSize := Socket.ReceiveLength();

    Try

    jpeg := TJpegimage.Create;

    GetMem(sData, TempSize);

    stream = TMemoryStream.Create();

    Socket.ReceiveBuf(sData,TempSize);

    stream.Position := 0 ;

    stream.Write(sData^, TempSize);

    Jpeg.LoadFromStream(stream);

    If Jpeg.Empty then Exit;

    Image.Picture.Assign(Jpeg);

    finally

    FreeMem(sData, TempSize);

    jpeg.Free;

    stream.Free;

    End;



    end;



    그런데 말이죠 이렇게 하면 에러는 안날거 같은데요

    문제는 저런식으로 데이터를 전송받으면 아마도 30kbyte이상 넘어가는거는

    다받지 못할것입니다



    제대로 받을려면.. 전송해주는 측에서 나이만큼 먼저 보낸다

    그럼 이걸 받거든 다 받았는가 확인하고

    다 받았으면 나에게 다음걸 보내주길 요청해라..

    또는 다 못받았으면

    Receivebuf로 나머지를 다 받은담에

    다음 데이터를 요청해라

    이런식이 되야 합니다



    그럼 이만



    ps: 참고로 전 요즘 c++ builder를 주로 하다 보니

    델파이 문법을 많이 까먹었읍니다..

    위에거 수정한것이지만..만약에 컴파일이 안되거든..

    함수선언부를 보고 수정해서 컴파일 해보세요