包已经收到,为什么总是读取不到UDP包的内容?(附代码)

很简短的一学习程序 使用一个TidUdpServer控件,所有属性默认,端口7788
点击一个按钮自己给自己发包,确信包已经收到,但是不知道怎么读取内容。

//Unit1.h头文件中定义一个结构体

typedef struct {
int TAG;
int LEN;
char* BUFFER;
}STN_HEAD;

//Unit1.cpp文件中发送部分
void __fastcall TForm1::Button3Click(TObject *Sender)
{
AnsiString ip=Edit1->Text; //这里输入是自己的IP

TStringList *dl=new TStringList(); //准备三组字符串,等会随机选择一个发送
dl->Add("DSDSDSDSDSDSDDSDFrom:192.168.1.29") ;
dl->Add("洒洒的三分三分2洒的12saa12啊");
dl->Add("搜索221斯蒂芬");

int j=random(3);
AnsiString data=dl->Strings[j];//随机选择内容体

STN_HEAD *packet=new STN_HEAD;
packet->TAG=(i+j);
packet->LEN= data.Length();
packet->BUFFER=new char[packet->LEN+1];
memcpy(packet->BUFFER,data.c_str(),data.Length());
int test=sizeof(STN_HEAD)+data.Length();
IdUDPServer1->SendBuffer(ip,7788,&packet,test);

Memo1->Lines->Add(AnsiString(packet->TAG)+":"+AnsiString((char*)packet->BUFFER)); //显示已发送的内容

delete packet;
delete dl;
}

//接受部分,以下代码不知哪里错,读不出整型数据和字符数据
void __fastcall TForm1::IdUDPServer1UDPRead(TObject *Sender,
TStream *AData, TIdSocketHandle *ABinding)
{
TMemoryStream *mio=new TMemoryStream();
int size=AData->Size; //长度和发送的一样,应该没有丢失数据
mio->SetSize(size);
mio->LoadFromStream(AData);
STN_HEAD *packet=new STN_HEAD;
//mio->Read((void*)packet,12); //这样读取也不行
mio->ReadBuffer(&packet->TAG,sizeof(int));
mio->ReadBuffer(&packet->LEN,sizeof(int));
packet->BUFFER=new char[packet->LEN+1];
mio->ReadBuffer(&packet->BUFFER,packet->LEN);

Memo2->Lines->Add(AnsiString(packet->TAG)+":"+AnsiString((char*)packet->BUFFER)); //显示收到内容
delete packet->BUFFER;
delete packet;
delete mio;

}

请高手看看,怎么读取一个结构体,里面有整型,有不定长度的缓冲区数据?
[2006 byte] By [proton-欲速则不达!] at [2008-1-9]
# 1
typedef struct {
int TAG;
int LEN;
char* BUFFER;
}STN_HEAD;

代码我没有看,但是只看这个结构体就知道你定义错误,不要用char*,要用char []
用char*,Ansistring这类东西只是记录一个地址,你传过去有什么用
其他代码我没有看,对不对就不知道了
# 2
那用 char [] 怎么动态分配内存呢? 我的这段内容是变长的数据, 怎么写?
proton-欲速则不达! at 2007-10-18 > top of Msdn China Tech,C++ Builder,基础类...
# 3
我想安吉尔已经指出你的问题所在了!!你发个packet实际上传了个地址过去,这个包有什么用啊?用数组阿,动态也没什么问题啊,有动态数组。或者分配个char buf[512]大点,能把你动态最长的都放得下就可以了。
foxyz-如风 at 2007-10-18 > top of Msdn China Tech,C++ Builder,基础类...
# 4
你可以设置你的最大长度,这样就行了,通讯都是要静态分配的,肯定都每帧都有最大的长度的,所以肯定可以用静态分配的.
yi10000 at 2007-10-18 > top of Msdn China Tech,C++ Builder,基础类...
# 5
刚才还回了一个人的类似错误,说是要把结构体写入文件再读出来,里面也定义了一个指针。呵呵,这样写进去指针就是个整形,4字节或者8字节,读出来有什么用啊?不行你就别结构体了,直接用实体类吧,写入的时候序列化类,读出来的时候动态恢复类。
foxyz-如风 at 2007-10-18 > top of Msdn China Tech,C++ Builder,基础类...
# 6
我已经改成
typedef struct {
int TAG;
int LEN;
char BUFFER[128];
}STN_HEAD;

但是还是读不出内容,不信你们试试

怎么读出两个个整型?一个字符数组?

proton-欲速则不达! at 2007-10-18 > top of Msdn China Tech,C++ Builder,基础类...
# 7
修改后的代码贴出来看看
IdUDPServer1->SendBuffer(ip,7788,&packet,test);//test 是多少


发送:
IdUDPServer1->SendBuffer(ip,7788,&packet,sizeof(STN_HEAD));

接受:
mio->ReadBuffer(packet,sizeof(STN_HEAD));

lother-阿艺 at 2007-10-18 > top of Msdn China Tech,C++ Builder,基础类...
# 8
代码如下:
发送:

AnsiString data=dl->Strings[j]; //前面略,没改
STN_HEAD *packet=new STN_HEAD;
packet->TAG=j;
packet->LEN= data.Length();
memcpy(packet->BUFFER,data.c_str(),data.Length());
int test=sizeof(STN_HEAD);
IdUDPServer1->SendBuffer(ip,7788,&packet,test);

接收:
STN_HEAD *packet=new STN_HEAD;
AData->ReadBuffer(&packet,sizeof(STN_HEAD));

//这里读完之后,我按ctril用调试窗口,看到包里面的字符串数据已经正确收到,但是结构体数字型的是错误的,是很大的两个数字,不是发送时指定的数字。
proton-欲速则不达! at 2007-10-18 > top of Msdn China Tech,C++ Builder,基础类...
# 9
htonl( )ntohl( )
你转一下看看不就知道了吗,一般在本地调试没有问题,仔细看看你的代码吧
# 10
我现在可以读出来整型数据了

接收的写法为:
STN_HEAD *packet=new STN_HEAD;
AData->Position = 0;
AData->ReadBuffer((void*)&packet,sizeof(STN_HEAD));
delete packet;

但是在IdUDPServer1UDPRead 函数结束的时候,就在 } 括号处报异常,并弹出cpu调试窗口:

Access violation at address 0x00000002 , Read of address 0x00000002 ....

这是内存溢出么?
proton-欲速则不达! at 2007-10-18 > top of Msdn China Tech,C++ Builder,基础类...
# 11
说明你的BUFFER[128]长度太短了,内容超长了,所以内存溢出,
你看看UDP规约,应该有个约定的,你这随便定义不行的.
yi10000 at 2007-10-18 > top of Msdn China Tech,C++ Builder,基础类...
# 12
问题最后并没有解决,期望帮助!再发一贴
proton-欲速则不达! at 2007-10-18 > top of Msdn China Tech,C++ Builder,基础类...