線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:927
推到 Plurk!
推到 Facebook!

傳結構後,消失了 1Byte

答題得分者是:RaynorPao
shinnuei
一般會員


發表:32
回覆:48
積分:21
註冊:2002-03-13

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-09-04 18:24:17 IP:61.221.xxx.xxx 未訂閱
各位先進好,小弟有一個結構的問題如下: 先說一下,這應該不算是 Internet 方面的問題,因為送出和收到的Bytes大小是一樣的…    先敘述一下我的問題, 我用了一個 NMUDP 來傳送Stream資料,而這個資料的內容是一個結構:
    struct scrStream
    {
        int SplitNum;
        int EWidth;
        int EHeight;
        TMemoryStream *MyStream;
    };
前面三個讀出來都是正確的,但是 MyStream 讀出來卻少了最後一個Byte (MyStream 是送出 "Edit1",收到時卻變成 "Edit") 以下是我的程式碼: 送出的程式碼
  TMemoryStream *MyStream = new TMemoryStream();
  TMemoryStream *tmpStream = new TMemoryStream();
  struct scrStream SendStream;
  int LenStr,LenStream;
  AnsiString C;      C = Edit1->Text;
  NMUDP1->RemoteHost    = "127.0.0.1";
  NMUDP1->ReportLevel   = Status_Basic;
  NMUDP1->RemotePort    = 6668;      SendStream.SplitNum   = 256;
  SendStream.EWidth     = 4;
  SendStream.EHeight    = 3;      LenStr = C.Length();
  tmpStream->Write(&C[1],LenStr);
  SendStream.MyStream   = tmpStream;
  LenStream = sizeof(SendStream);         //從這裡得知送出 16 Bytes      MyStream->Write(&SendStream, LenStream);
  NMUDP1->SendStream(MyStream);
收到的程式碼(NMUDP1DataReceived)
  AnsiString C;
  TMemoryStream *MyStream = new TMemoryStream();
  TMemoryStream *tmpStream = new TMemoryStream();
  struct scrStream RecvStream;      NMUDP1->ReadStream(MyStream);
  MyStream->Read(&RecvStream,NumberBytes);
  int LenStream = sizeof(RecvStream.MyStream);    //從這裡得知收到也是 16 Bytes
  C.SetLength(LenStream);
  RecvStream.MyStream->Read(&C[1],LenStream);      Memo2->Lines->Add("RecvStream.SplitNum ="      (String)RecvStream.SplitNum     "\n"  
                    "RecvStream.EWidth   ="      (String)RecvStream.EWidth       "\n"  
                    "RecvStream.EHeight  ="      (String)RecvStream.EHeight      "\n"  
                    "C ="   C);
既然送出和收到是一樣的(我是用 Bytes 去判斷,因為我不知道要怎麼看 Stream 的內容),那為什麼要把這個結構裡的 Stream 讀出來時會少了一個Byte呢? 感謝...
RaynorPao
版主


發表:139
回覆:3622
積分:7025
註冊:2002-08-12

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-09-04 20:04:58 IP:61.221.xxx.xxx 未訂閱
引言: 各位先進好,小弟有一個結構的問題如下: 先說一下,這應該不算是 Internet 方面的問題,因為送出和收到的Bytes大小是一樣的… 先敘述一下我的問題, 我用了一個 NMUDP 來傳送Stream資料,而這個資料的內容是一個結構:
    struct scrStream
    {
        int SplitNum;
        int EWidth;
        int EHeight;
        TMemoryStream *MyStream;
    };
前面三個讀出來都是正確的,但是 MyStream 讀出來卻少了最後一個Byte (MyStream 是送出 "Edit1",收到時卻變成 "Edit") 以下是我的程式碼: 送出的程式碼
  TMemoryStream *MyStream = new TMemoryStream();
  TMemoryStream *tmpStream = new TMemoryStream();
  struct scrStream SendStream;
  int LenStr,LenStream;
  AnsiString C;      C = Edit1->Text;
  NMUDP1->RemoteHost    = "127.0.0.1";
  NMUDP1->ReportLevel   = Status_Basic;
  NMUDP1->RemotePort    = 6668;      SendStream.SplitNum   = 256;
  SendStream.EWidth     = 4;
  SendStream.EHeight    = 3;      LenStr = C.Length();
  tmpStream->Write(&C[1],LenStr);
  SendStream.MyStream   = tmpStream;
  LenStream = sizeof(SendStream);         //從這裡得知送出 16 Bytes      MyStream->Write(&SendStream, LenStream);
  NMUDP1->SendStream(MyStream);
收到的程式碼(NMUDP1DataReceived)
  AnsiString C;
  TMemoryStream *MyStream = new TMemoryStream();
  TMemoryStream *tmpStream = new TMemoryStream();
  struct scrStream RecvStream;      NMUDP1->ReadStream(MyStream);
  MyStream->Read(&RecvStream,NumberBytes);
  int LenStream = sizeof(RecvStream.MyStream);    //從這裡得知收到也是 16 Bytes
  C.SetLength(LenStream);
  RecvStream.MyStream->Read(&C[1],LenStream);      Memo2->Lines->Add("RecvStream.SplitNum ="      (String)RecvStream.SplitNum     "\n"  
                    "RecvStream.EWidth   ="      (String)RecvStream.EWidth       "\n"  
                    "RecvStream.EHeight  ="      (String)RecvStream.EHeight      "\n"  
                    "C ="   C);
既然送出和收到是一樣的(我是用 Bytes 去判斷,因為我不知道要怎麼看 Stream 的內容),那為什麼要把這個結構裡的 Stream 讀出來時會少了一個Byte呢? 感謝...
shinnuei 你好:
(1)因為 TMemoryStrema* 只佔 4 個 bytes 的記憶體
(2)建議你的 structure 改成以下這個樣子寫
typedef struct _scrStream
{
   int SplitNum;
   int EWidth;
   int EHeight;
   BYTE bStream[1024];
   DWORD dwLen;
} scrStream;
(3)在傳送的時候,先把 MemoryStream 裡面的資料放到 bStream 裡面,長度則
   放到 dwLen 裡面,這樣子應該就不會錯了
(4)不過這樣子做的時候,要先確定 MemoryStream 裡面的資料長度不會超過
   1024 bytes,如果超過的話,就要分次傳送
-- Enjoy Researching & Developing --
------
-- 若您已經得到滿意的答覆,請適時結案!! --
-- 欲知前世因,今生受者是;欲知來世果,今生做者是 --
-- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 --
shinnuei
一般會員


發表:32
回覆:48
積分:21
註冊:2002-03-13

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-09-04 20:51:28 IP:61.221.xxx.xxx 未訂閱
謝謝RaynorPao的回答,不過小弟的疑問還是沒有解決說… 就(1)來說,為什麼他只佔 4 bytes呢? 而且我剛試了一下…真的只有 4Bytes!    
引言: C = Edit1->Text; NMUDP1->RemoteHost = "127.0.0.1"; NMUDP1->ReportLevel = Status_Basic; NMUDP1->RemotePort = 6668; SendStream.SplitNum = 256; SendStream.EWidth = 4; SendStream.EHeight = 3; LenStr = C.Length(); tmpStream->Write(&C[1],LenStr); SendStream.MyStream = tmpStream; int test = sizeof(SendStream.MyStream); //加入這一行,真的只有 4 bytes!! LenStream = sizeof(SendStream); //從這裡得知送出 16 Bytes MyStream->Write(&SendStream, LenStream); NMUDP1->SendStream(MyStream);
為什麼會這樣哩?這一次寫入Stream還沒經過網路傳送就己經剩 4Bytes了... 而 (2)、(3)、(4)的做法覺得比較麻煩(首先要傳送的大小未知,所以結構中的宣告只能設 某一值,多了還要另外做其他處理、少了有點浪費)
RaynorPao
版主


發表:139
回覆:3622
積分:7025
註冊:2002-08-12

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-09-04 21:10:41 IP:61.221.xxx.xxx 未訂閱
引言: 謝謝RaynorPao的回答,不過小弟的疑問還是沒有解決說… 就(1)來說,為什麼他只佔 4 bytes呢? 而且我剛試了一下…真的只有 4Bytes!
引言: C = Edit1->Text; NMUDP1->RemoteHost = "127.0.0.1"; NMUDP1->ReportLevel = Status_Basic; NMUDP1->RemotePort = 6668; SendStream.SplitNum = 256; SendStream.EWidth = 4; SendStream.EHeight = 3; LenStr = C.Length(); tmpStream->Write(&C[1],LenStr); SendStream.MyStream = tmpStream; int test = sizeof(SendStream.MyStream); //加入這一行,真的只有 4 bytes!! LenStream = sizeof(SendStream); //從這裡得知送出 16 Bytes MyStream->Write(&SendStream, LenStream); NMUDP1->SendStream(MyStream);
為什麼會這樣哩?這一次寫入Stream還沒經過網路傳送就己經剩 4Bytes了... 而 (2)、(3)、(4)的做法覺得比較麻煩(首先要傳送的大小未知,所以結構中的宣告只能設 某一值,多了還要另外做其他處理、少了有點浪費)
shinnuei 你好:
(1)因為在 Win32 的環境裡面,任何指標 (int*, BYTE*, void*,...) 都佔 4
   個 BYTES 的記憶體空間,但是它實際存放資料的地方,是這個指標所指向
   的記憶體位置,因此,就算你的實體資料有 512 bytes,但是你對指標做
   sizeof 的運算,當然只有 4 個 bytes
(2)小弟我建議你的方式,算是最簡單、方便的方式了,如果你想要傳送的資料
   的長度會不斷變化,而且差距非常大的話,這個方法可能還需要做另外一番
   修正,可是如果你傳送的資料長度的變化都不會很大的話,甚至很小的話 (
   例如: 所有傳送的資料都小於 256 bytes),那就先暫時使用這個方法吧,
   自己可以依照需求,把那個 BYTE array 設小一點
-- Enjoy Researching & Developing --
------
-- 若您已經得到滿意的答覆,請適時結案!! --
-- 欲知前世因,今生受者是;欲知來世果,今生做者是 --
-- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 --
shinnuei
一般會員


發表:32
回覆:48
積分:21
註冊:2002-03-13

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-09-05 00:41:24 IP:61.221.xxx.xxx 未訂閱
感謝 RaynorPao 解決了我的疑惑... 我現在把結構改成這樣,傳送的時候順便把 Size 也傳過去…
    struct scrStream
    {
        int SplitNum;
        int EWidth;
        int EHeight;
        int Size;
        TMemoryStream *MyStream;
    };
PS:用BYTE傳有什麼優點嗎?
RaynorPao
版主


發表:139
回覆:3622
積分:7025
註冊:2002-08-12

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-09-05 08:45:05 IP:203.73.xxx.xxx 未訂閱
引言: 感謝 RaynorPao 解決了我的疑惑... 我現在把結構改成這樣,傳送的時候順便把 Size 也傳過去…
    struct scrStream
    {
        int SplitNum;
        int EWidth;
        int EHeight;
        int Size;
        TMemoryStream *MyStream;
    };
PS:用BYTE傳有什麼優點嗎?
shinnuei 你好: 老話一句,還是建議你把最後一個變數改成 BYTE array,你現在的寫法在對整 個 structure 做 sizeof 運算的時候,應該得到的只有 20 個 bytes,除非配 合程式碼的大幅修改,才能避免你之前的錯誤;然而,如果改成 BYTE array 的 話,你的程式碼就不用改那麼多 (小幅修改即可) -- Enjoy Researching & Developing --
------
-- 若您已經得到滿意的答覆,請適時結案!! --
-- 欲知前世因,今生受者是;欲知來世果,今生做者是 --
-- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 --
shinnuei
一般會員


發表:32
回覆:48
積分:21
註冊:2002-03-13

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-09-05 10:48:46 IP:61.221.xxx.xxx 未訂閱
哈,真的是應驗了一句話"不聽老人言,吃虧在眼前" 換來的是浪費了一個多小時… 再次感謝 RaynorPao
系統時間:2024-06-16 10:19:06
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!