TCP通信时,发送缓冲区用结构体表示,结构体中定义的变量能否不固定大小.
如题目的意思
如果没清楚意思,看下面代码
定义了一个公共模块,客户端和服务端程序都引用他
unit GlobalUnit;
interface
type
PCommBlock = ^TCommBlock; //自定义了一个结构体指针TCommBlock
TCommBlock = packed record // the Communication Block used in both parts (Server+Client)
Command,
MyUserName, // the sender of the message (by DNS name)
Msg, // the message itself
ReceiverName: string[100]; // name of receiver //信息不能超过100字符大小是硬伤 这样传输效率明显不高
cid:integer; //用来确定反馈信息在哪输出的
loginflag:Boolean;
username:string; //不规定大小的情况缓冲区的大小会变化 sizeof没有结果 不知道delphi内存怎么分配结构体内存的
password:string; //发送的时候给了值 可以得到大小 接受的时候没有合适的大小去匹配
end;
implementation
end.
//向服务端发送登录请求返回通信命令协议加密串,使得软件和以和服务端交互
CommBlock.Command := 'Login'; // assign the data
CommBlock.MyUserName := Client.LocalName;
CommBlock.Msg := 'login test';//可以自定义协议串 或者用二进制数据传输一个结构体 需要定义一个完善的命令协议
CommBlock.ReceiverName := '';
CommBlock.username :='admin';
CommBlock.password :='xxx';
Client.WriteBuffer (CommBlock, SizeOf (CommBlock), true);
AThread.Connection.ReadBuffer (CommBlock, SizeOf (CommBlock));//执行到这里就出错
command_do(CommBlock,Protocol,Clients);//这是自定义的函数用来处理命令的
//在这里先发送CommBlock的大小
length:=SizeOf (CommBlock);
Client.WriteBuffer (length, 4, true);
Client.WriteBuffer (CommBlock, SizeOf (CommBlock), true);
var
m_PCommBlock:PCommBlock;
begin
//略.......
//先读出CommBlock的大小 再给CommBlock的指针m_PCommBlock分配内存
AThread.Connection.ReadBuffer (buffersize, 4);
GetMem(m_PCommBlock,buffersize); //分配内存
CommBlock :=m_PCommBlock^;//在这里加入赋值来测试结果 发现在这里就出错了
//仔细想想也是不行 CommBlock依然是大小不对的吧
AThread.Connection.ReadBuffer (m_PCommBlock^, buffersize);
//然后读入到m_PCommBlock这也不行?
end;
ReceiverName: string[100];
cid:integer;
loginflag:Boolean;
usernameLen:int; //UserName对应的字符串的长度
passwordLen:int; //Password对应的字符串的长度
end;
写完Block后再写入UserName和Password两个字符串
读取的时候先读取Block获取两个字符串的长度,然后从流中按取得的长度分别读取UserName和Password两个字符串
[解决办法]
你这里结构体里面不能有不定长度的类型,如string
不定长一定要改为定长,否则你不要用结构体,改为XML或JSON封装,然后传一个封装完的长string,用buff+size方式传递
[解决办法]
二进制格式,运行效率最高,空间效率一般(部分域因为按最大空间预留,也可能浪费),但是最不灵活
现在应该采用灵活的xml/json/ini作为数据表达协议,只要效率限制允许
[解决办法]
介于二进制结构和xml/json/ini之间,还有一种协议:
tlv(tag-length-value)
[解决办法]
不能。 。
[解决办法]
每块是定长,但是块数可变
[解决办法]
username :array[0..49] of char;...
试试
[解决办法]
到Torry下载个JDSockets,省了造轮子的麻烦