全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:7003
推到 Plurk!
推到 Facebook!

ReceiveBuf()的問題

答題得分者是:brook
randompart
一般會員


發表:1
回覆:5
積分:1
註冊:2011-11-11

發送簡訊給我
#1 引用回覆 回覆 發表時間:2011-11-11 00:43:50 IP:114.35.xxx.xxx 訂閱
我先在類別外宣告了一個結構
struct test{
int num;
char ch;
}test1;

在server端設定初值
void __fastcall TForm1::FormCreate(TObject *Sender)
{
test1.num=1;
test1.ch='b';
}

然後在server端拉個button出來,希望按下之後資料能顯示在clien端t的memo上(show)
void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
int i;
for(i=0;iSocket->ActiveConnections;i )
ServerSocket1->Socket->Connections[i]->SendBuf(&test1,sizeof(test1));
}

client端的寫法
void __fastcall TForm1::ClientSocket1Read(TObject *Sender,
TCustomWinSocket *Socket)
{
int j;
test get;
get.num=0;
get.ch='a';
j=Socket->ReceiveLength();
Socket->ReceiveBuf(&get,j);
show->Lines->Add(AnsiString(get.num) AnsiString(get.ch));
}

但是程式剛開始server和client連線後馬上出現socket error 10053,client端自動關閉,請問這種情形是?
但是只要把Socket->ReceiveBuf(&get,j);這行砍掉就沒錯誤了。

編輯記錄
randompart 重新編輯於 2011-11-10 10:24:20, 註解 無‧
brook
資深會員


發表:57
回覆:323
積分:371
註冊:2002-07-12

發送簡訊給我
#2 引用回覆 回覆 發表時間:2011-11-16 12:50:03 IP:60.251.xxx.xxx 訂閱
你的 test get; 才5個byte,如何存幾百的byte呢?
randompart
一般會員


發表:1
回覆:5
積分:1
註冊:2011-11-11

發送簡訊給我
#3 引用回覆 回覆 發表時間:2011-11-17 23:29:49 IP:114.35.xxx.xxx 訂閱
不好意思,我不太懂,我不是只傳了一個int及一個char嗎?  幾百個byte指的是?
brook
資深會員


發表:57
回覆:323
積分:371
註冊:2002-07-12

發送簡訊給我
#4 引用回覆 回覆 發表時間:2011-11-19 13:00:17 IP:60.251.xxx.xxx 訂閱
1.先檢查 j=Socket->ReceiveLength();    j值是多少bytes
2.再來char *p = new char[j];
3.用完記得 delete []p;
4.就像你開信箱發現己寄來十幾封信,你的memory夠用嗎?
randompart
一般會員


發表:1
回覆:5
積分:1
註冊:2011-11-11

發送簡訊給我
#5 引用回覆 回覆 發表時間:2011-11-26 21:09:15 IP:114.35.xxx.xxx 訂閱
感謝指導,總算是解決socket  error的問題,以下是修改後的程式碼,標頭檔宣告
struct test{
int num;
char ch;
}test1;

void __fastcall TForm1::ClientSocket1Read(TObject *Sender,
TCustomWinSocket *Socket)
{
int j;
j=Socket->ReceiveLength();
char* get=new char[j];
Socket->ReceiveBuf(get,j);
memcpy(&test1,get,sizeof(test1));
delete []get;
}

我還有個疑惑是,我知道我只傳1個int及1個char,那大小應該是5個byte而已,但是在這行
char* get=new char[j];
改成
char* get=new char[10];
會出現access violation at address的錯誤訊息,請問是為何?

brook
資深會員


發表:57
回覆:323
積分:371
註冊:2002-07-12

發送簡訊給我
#6 引用回覆 回覆 發表時間:2011-11-28 07:43:47 IP:60.251.xxx.xxx 訂閱
詳細的情況我不是很清楚,不過有可能3個封包同時到,也可能收到垃圾資料.
要不然就當收到超10個bytes時,你就一次就讀10個bytes就好.
randompart
一般會員


發表:1
回覆:5
積分:1
註冊:2011-11-11

發送簡訊給我
#7 引用回覆 回覆 發表時間:2011-12-02 01:00:40 IP:114.35.xxx.xxx 訂閱
不好意思,我又有問題了= =
如果我傳的struct有兩種類型 比如說struct1的成員有一個int及一個char,而struct2成員有兩個int及一個char
那我在接收的時候要用哪種變數去接收?

之前因為我知道我只傳一種結構struct1,所以可以寫

j=Socket->ReceiveLength();
char* get=new char[j];
Socket->ReceiveBuf(get,j);
memcpy(&test1,get,sizeof(test1));

test1是struct1的變數,將資料copy到test1裡。

但如果我傳送兩種結構,我就不知道該把資料copy至哪個struct的變數裡,請問我該怎麼做(該如何識別現在傳來的結構是屬於哪一個?)

再次謝謝幫助。



編輯記錄
randompart 重新編輯於 2011-12-01 10:02:14, 註解 無‧
randompart 重新編輯於 2011-12-01 10:02:33, 註解 無‧
brook
資深會員


發表:57
回覆:323
積分:371
註冊:2002-07-12

發送簡訊給我
#8 引用回覆 回覆 發表時間:2011-12-02 11:47:20 IP:60.251.xxx.xxx 訂閱
一般我會在前面加個表頭,如:
struct Txn{
char A; //固定放一個數字如 0xff,表示你的資料從這裡開始
unsigned char RecType; //用來分別你的struct型態.
unsigned short RecNo; //存資料大小.
};

將表頭和你的struct一起傳出去,如此你就可以用這個表頭來分別你的資料型態.
randompart
一般會員


發表:1
回覆:5
積分:1
註冊:2011-11-11

發送簡訊給我
#9 引用回覆 回覆 發表時間:2011-12-02 13:23:10 IP:114.35.xxx.xxx 訂閱
感謝回答,其實我有想到要加個標頭識別,我不懂的是要如何單獨讀取到標頭的資料?
編輯記錄
randompart 重新編輯於 2011-12-01 22:23:33, 註解 無‧
brook
資深會員


發表:57
回覆:323
積分:371
註冊:2002-07-12

發送簡訊給我
#10 引用回覆 回覆 發表時間:2011-12-02 20:58:27 IP:140.124.xxx.xxx 訂閱

[code cpp]
struct Txn{
char A; //固定放一個數字如 0xff,表示你的資料從這裡開始
unsigned char RecType; //用來分別你的struct型態.
unsigned short RecNo; //存資料大小.
};

void __fastcall TForm1::ClientSocket1Read(TObject *Sender,
TCustomWinSocket *Socket)
{
int i;
Txn *a;
char *p;

i=Socket->ReceiveLength();
if (i>0)
{
p = new char[i];
if (p)
{
Socket->ReceiveBuf(p,i);
a = (Txn*)p; //表頭指向你收到資料的位置
if (a->A == 0xff) //表示這是你的資料
{
if (a->RecNo == i) //當你收到的資料和記錄的不一樣時,少收就必須和下一筆連接起來處理,多收的話可能會2個RECORD,要不然不相等就當垃圾不處理也行.
{
if (a->RecType == 1) //第一種狀況
{
test *get;
get = (test*)&p[sizeof(Txn)]; //真正資料開始位置
get-> num; //這就是你的資料,再來就是你該如何處理資料
get->ch;
}

if (a->RecType == 2) //第二種狀況
{
test2 *get; //你的第二種格
get = (test*)&p[sizeof(Txn)];
}
}
}
delete []p;
}
}
}

[/code]
家裡沒灌BCB,你自己先測看看.
編輯記錄
brook 重新編輯於 2011-12-02 06:00:27, 註解 無‧
brook 重新編輯於 2011-12-02 06:01:53, 註解 無‧
brook 重新編輯於 2011-12-02 06:03:51, 註解 無‧
randompart
一般會員


發表:1
回覆:5
積分:1
註冊:2011-11-11

發送簡訊給我
#11 引用回覆 回覆 發表時間:2011-12-23 13:33:56 IP:114.35.xxx.xxx 訂閱
抱歉,這段時間事忙,沒有空閑練程式,不及回覆。

程式可行,感謝指導,讓我學到不少!!


系統時間:2024-11-21 16:57:10
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!