想要一个在indy10下,用内存流发送结构的例子,最好是同步通信的

blacktulipg 2010-12-31 10:21:10
使用BCB2010,indy10,需要内存流发送结构的例子,最好是同步通信的
...全文
199 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
周药师 2010-12-31
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 blacktulipg 的回复:]

一定需要用disconnect来结束流发送吗,难道不能以同步通信方式进行吗,就像发送字符串一样
[/Quote]
当然可以了 你开始连上后 可以一直去发送的

void __fastcall TForm1::Button3Click(TObject *Sender)
{
IdTCPClient1->Port = 8000;
IdTCPClient1->Host = "127.0.0.1";
IdTCPClient1->Connect();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button4Click(TObject *Sender)
{
TMemoryStream * Strm = new TMemoryStream ();
userInfo aUser ;
_tcscpy(aUser.name,"张三") ;
_tcscpy(aUser.passWord,"123") ;
Strm->Write(&aUser,sizeof(userInfo));
Strm->Position = 0 ;
IdTCPClient1->IOHandler->Write(Strm);
delete Strm ;
}
//---------------------------------------------------------------------------

blacktulipg 2010-12-31
  • 打赏
  • 举报
回复
另外,如果只发送TMemoryStream的Memory部分,接收端怎样接收呢
blacktulipg 2010-12-31
  • 打赏
  • 举报
回复
一定需要用disconnect来结束流发送吗,难道不能以同步通信方式进行吗,就像发送字符串一样
周药师 2010-12-31
  • 打赏
  • 举报
回复
要用流的城市发送结构体
http://topic.csdn.net/u/20101222/14/6acaba66-691d-44de-95c4-28b572140089.html
我在3楼的代码
发送部分改成这样就行了

void __fastcall TForm1::Button2Click(TObject *Sender)
{
TMemoryStream * Strm = new TMemoryStream ();
userInfo aUser ;
_tcscpy(aUser.name,"张三") ;
_tcscpy(aUser.passWord,"123") ;
//TBytes buffer;
//buffer=RawToBytes(&aUser, sizeof(userInfo));
Strm->Write(&aUser,sizeof(userInfo));
Strm->Position = 0 ;
IdTCPClient1->Port = 8000;
IdTCPClient1->Host = "127.0.0.1";
IdTCPClient1->Connect();
IdTCPClient1->IOHandler->Write(Strm);
//IdTCPClient1->IOHandler->Write(buffer);
IdTCPClient1->Disconnect();
delete Strm ;
}
//
周药师 2010-12-31
  • 打赏
  • 举报
回复
我在8楼的代码里

Strm->ReadBuffer(&aComuniContent,sizeof(comuniContent));
这段代码已经还原成结构体了

void __fastcall TForm2::IdTCPServer1Execute(TIdContext *AContext)
{
comuniContent aComuniContent ;
userInfo aUser;
pCInfo CInfo ;
TMemoryStream * Strm = new TMemoryStream ();
try
{
try
{
//这里直接转换成结构体了
AContext->Connection->IOHandler->ReadStream(Strm,sizeof(comuniContent));
Strm->Position = 0 ;
//
//注意 这个地方还原了结构体aComuniContent
//
Strm->ReadBuffer(&aComuniContent,sizeof(comuniContent));
//得到了结构体了
aUser = aComuniContent.user;
CInfo = aComuniContent.host ;
//其他的结构体类似 你自己去完成吧
Memo1->Lines->Add("唯一标识符:"+AnsiString(aComuniContent.SN));
Memo1->Lines->Add("用户名:"+AnsiString(aUser.name));
Memo1->Lines->Add("密码:"+AnsiString(aUser.passWord));
Memo1->Lines->Add("计算机名字:"+AnsiString(CInfo.pCName));
Memo1->Lines->Add("IP地址:"+AnsiString(CInfo.pCIP));
Memo1->Lines->Add("MAC地址:"+AnsiString(CInfo.nWMak));
Memo1->Lines->Add("端口号:"+AnsiString(CInfo.port));
}
catch (Exception &e)
{
Memo1->Lines->Add("读取登录信息异常");
}
}
__finally
{
delete Strm;
}
}
//---------------------------------------------------------------------------
blacktulipg 2010-12-31
  • 打赏
  • 举报
回复
我不明白,当结构写入内存流以后,强制转换成字符数组发送,接收端收到一个字符数组,写入字符串。但是怎么样转换成原来的结构呢?
周药师 2010-12-31
  • 打赏
  • 举报
回复
enUTF8是一个字符集 是一种针对Unicode的可便长度字元编码(定长码)
由于CB2010默认的Unicode编码
所以在发送接收的时候制定enUTF8方式去处理就行了

“读出数据怎么样操作呢
还要写入流中然后read或者readbuffer吗”

str 就是读出来的数据了 已经是看得见的一个字符串了
你还要写到流里去干嘛?
blacktulipg 2010-12-31
  • 打赏
  • 举报
回复
周药师代码
发送端
IdTCPClient1->IOHandler->WriteLn(ptr,enUTF8);
不知道enUTF8意思,是内存流通用的结束符号吗?

接收端
UnicodeString str;
str=AContext->Connection->IOHandler->ReadLn(enUTF8);

读出数据怎么样操作呢
还要写入流中然后read或者readbuffer吗
周药师 2010-12-31
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 blacktulipg 的回复:]

我实在看不出以上代码的问题
[/Quote]

又来了个问题了
我给你做个简单的例子吧
我把WideChar全部换成了通用类型TCHAR

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit2.h"
#include <TCHAR.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "IdBaseComponent"
#pragma link "IdComponent"
#pragma link "IdContext"
#pragma link "IdCustomTCPServer"
#pragma link "IdTCPClient"
#pragma link "IdTCPConnection"
#pragma link "IdTCPServer"
#pragma resource "*.dfm"
TForm2 *Form2;
struct userInfo//用户
{
TCHAR name[16];
TCHAR passWord[16];
};

struct pCInfo//本机
{
TCHAR pCName[16];
TCHAR pCIP[25];
TCHAR nWMak[40];//网卡Mak
int port;
};

struct command//命令
{
TCHAR commandC;//用1个字符代表命令,查阅本文件中的Define表
TCHAR receiver1[16];//接受者,要执行接收的命令
TCHAR receiver2[16];//接受者,发送给某个客户端时使用
TCHAR word[200];//发送的谈话内容
};
struct comuniContent//发送的信息
{
TCHAR SN[8];//唯一标识符
userInfo user;
pCInfo host;
command aCommand;
};


//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Button3Click(TObject *Sender)
{
IdTCPClient1->Port = 8000;
IdTCPClient1->Host = "127.0.0.1";
IdTCPClient1->Connect();
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Button4Click(TObject *Sender)
{
TMemoryStream * Strm = new TMemoryStream();
userInfo aUser ;
_tcscpy(aUser.name,"张三") ;
_tcscpy(aUser.passWord,"123") ;
pCInfo aCInfo ;
_tcscpy(aCInfo.nWMak,"PC") ;
_tcscpy(aCInfo.pCIP,"192.168.0.88") ;
_tcscpy(aCInfo.nWMak,"888-666-888") ;
aCInfo.port = 8000;

command acommand;
acommand.commandC = 'D' ;
_tcscpy(acommand.receiver1,"AA") ;
_tcscpy(acommand.receiver2,"BB") ;
_tcscpy(acommand.word,"3860") ;

comuniContent aComuniContent ;
_tcscpy(aComuniContent.SN ,"001") ;
aComuniContent.user = aUser ;
aComuniContent.host = aCInfo ;
aComuniContent.aCommand = acommand ;

Strm->Write(&aComuniContent,sizeof(aComuniContent));
Strm->Position = 0 ;
IdTCPClient1->IOHandler->Write(Strm);
delete Strm ;
}
//---------------------------------------------------------------------------

void __fastcall TForm2::IdTCPServer1Execute(TIdContext *AContext)
{
comuniContent aComuniContent ;
userInfo aUser;
pCInfo CInfo ;
TMemoryStream * Strm = new TMemoryStream ();
try
{
try
{
AContext->Connection->IOHandler->ReadStream(Strm,sizeof(comuniContent));
Strm->Position = 0 ;
Strm->ReadBuffer(&aComuniContent,sizeof(comuniContent));
aUser = aComuniContent.user;
CInfo = aComuniContent.host ;
//其他的结构体类似 你自己去完成吧
Memo1->Lines->Add("唯一标识符:"+AnsiString(aComuniContent.SN));
Memo1->Lines->Add("用户名:"+AnsiString(aUser.name));
Memo1->Lines->Add("密码:"+AnsiString(aUser.passWord));
Memo1->Lines->Add("计算机名字:"+AnsiString(CInfo.pCName));
Memo1->Lines->Add("IP地址:"+AnsiString(CInfo.pCIP));
Memo1->Lines->Add("MAC地址:"+AnsiString(CInfo.nWMak));
Memo1->Lines->Add("端口号:"+AnsiString(CInfo.port));
}
catch (Exception &e)
{
Memo1->Lines->Add("读取登录信息异常");
}
}
__finally
{
delete Strm;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm2::FormShow(TObject *Sender)
{
IdTCPServer1->DefaultPort = 8000;
IdTCPServer1->Active = true ;
}
//---------------------------------------------------------------------------

blacktulipg 2010-12-31
  • 打赏
  • 举报
回复
我实在看不出以上代码的问题
blacktulipg 2010-12-31
  • 打赏
  • 举报
回复
我尝试了发送过程,不成功,过程如下:
定义一个结构
struct userInfo//用户
{
WideChar name[16];
WideChar passWord[16];
};

struct pCInfo//本机
{
WideChar pCName[16];
WideChar pCIP[25];
WideChar nWMak[40];//网卡Mak
int port;
};

struct command//命令
{
WideChar commandC;//用1个字符代表命令,查阅本文件中的Define表
WideChar receiver1[16];//接受者,要执行接收的命令
WideChar receiver2[16];//接受者,发送给某个客户端时使用
WideChar word[200];//发送的谈话内容
};

struct comuniContent//发送的信息
{
WideChar SN[8];//唯一标识符
userInfo user;
pCInfo host;
command aCommand;
};
comuniContent aComuniContent;
//aComuniContent赋值

客户端发送
TMemoryStream *aMemoryStream=new TMemoryStream();
aMemoryStream->Write(&aComuniContent, sizeof(comuniContent));//写入内存流
记录aMemoryStream->Size
aMemoryStream->Position=0;
IdTCPClient1->IOHandler->Write(aMemoryStream);

服务器接收
AContext->Connection->IOHandler->ReadStream(aMemoryStream, 716, false);
//716是根据记录aMemoryStream->Size来的

以上代码接收端会发生异常或数据无法读出,想知道原因

现已改用BCB2010
周药师 2010-12-31
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 blacktulipg 的回复:]

另外,如果只发送TMemoryStream的Memory部分,接收端怎样接收呢
[/Quote]


void __fastcall TForm1::Button3Click(TObject *Sender)
{
IdTCPClient1->Port = 8000;
IdTCPClient1->Host = "127.0.0.1";
IdTCPClient1->Connect();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button4Click(TObject *Sender)
{
TMemoryStream * Strm = new TMemoryStream ();
userInfo aUser ;
_tcscpy(aUser.name,"张三") ;
_tcscpy(aUser.passWord,"123") ;
Strm->Write(&aUser,sizeof(userInfo));
Strm->Position = 0 ;
TCHAR *ptr=(TCHAR *)(Strm->Memory);
IdTCPClient1->IOHandler->WriteLn(ptr,enUTF8);
delete Strm ;
}


void __fastcall TForm1::IdTCPServer1Execute(TIdContext *AContext)
{
UnicodeString str;
str = AContext->Connection->IOHandler->ReadLn(enUTF8);
Memo1->Lines->Add(str) ;
}

1,317

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 网络及通讯开发
社区管理员
  • 网络及通讯开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧