个数据域比如是这样定义的
type
TSocketMessage = record
MessageType: integer;
From: PChar;
Msg: PChar;
end;
那么如何发送呀?再说我接到信息后不能只通过
Socket.ReceiveText(S);
当字符串接收,因为我发送时是按照记录类型发送的,接收时也应该是拿记录来接收然后分析出MessageType,From,Msg三个数据域的值再继续处理。怎么办?
5:即然Integer怎么发你知道了,那怎么发送不定长的数据不难吧。
TCP是基于Stream发送数据的概念,不是说你发两次'abc',另一端就会触发两次,每次一个'abc',它是可能会是乱七八糟的触发的。所以,你自己还得管理一下接收的处理。
如:
Client:
Send Len(Integer);
Send Data(0..Len - 1)
Server:
Recv Len
Recv Data(0..Len - 1)
有了这个Data,怎么分隔那是另一回事。
明白上面的了,那两个PChar,三个也没问题啊。
不过,实际中,只是做一次Send PChar的上面的处理,不然,写起手累啊,因为,传输是传输,解析让另外的回调啊,事件啊,什么什么的去做吧。
不说了,费话多了。
6: 我的目的就是把命令和数据在同一个包里发送,这样的话编程比较简单,思路比较清楚,如果记录类型不行那用什么方法发送好呢?
7:对于复杂结构,可以使用流来发送
var
tempLen: Integer;
TempStream : TMemoryStream;
begin
TempStream := TMemoryStream.Create;
// 发送定义格式类型时直接发送内容
tempInt := 10;
TempStream.WriteBuffer(@pack.MessageType, sizeof(Integer));
// 发送非定义格式类型时,数据前带有四个字节的长度内容 tempLen := Length(pack.Msg); TempStream.WriteBuffer(@tempLen, sizeof(Integer)); TempStream.WriteBuffer(pack.Msg, tempLen); ... TempStream.Position := 0; ClientSocket1.Socket.SendStream(TempStream); TempStream.Free; end; 接收到数据时,使用同样的顺序取出记录项即可,这和FMC的串行化方式类似。 但在接收数据时,必须进行边界处理,因为你不一定会在一个包中得到完整的数据。 以上代码没调试过,可以有问题,但基本思想就在里面。 8: 楼上说的有理,不过接收时候无法知道包里数据的长度呀! tempLen := ??; TempStream.ReadBuffer(pack.Msg, tempLen); 9:写的时候先写入长度啊: TmpStream.Write(Length(Str), SizeOf(Integer)); // 先写入长度 TmpStream.Write(Str[1], SizeOf(Str)); 读的时候就先读长度: TmpStream.Read(tmpLen, SizeOf(Integer)); // 先读取长度 SetLength(pack.Msg, tmpLen); // 记得先分配空间 TmpStream.Read(pack.Msg, tmpLen); 10:发送时先发送要发送流的长度然后再发送流,接收时先收长度,在按长度接收流,随便 发什么都是这样,不会有问题。
如果长度太大可以分成几部分, 每接收一部分返回成功信息否则返回失败信息。 发送方收到 成功信息后再发下一包否则重发当前包。
11:多人接受答案了。