Type
SendData=packed record
Command:string[5];
Content:string[255]; //不用数组服务器读不到,加上又不能完全发送,而且最大只能255
end;
如何修改?我的做法如下
Type
SendData=packed record
Command:string[5];
Content:array[0..1024] of char;
end;var SendData:TSendData;
begin
FillChar(SendData,SizeOf(SendData),0);
StrPCopy(@SendData.Command,'send');
StrPCopy(@SendData.Content,EdtMsg.Text);
IdTcpClient.WriteBuffer(SendData,SizeOf(SendData),True);
end;服务器端这样取
ShowMessage(StrPas(@SendData.Content));其他的答案大家分享下,比如使用PChar,Byte本人抛砖引玉,大家踊跃发言哈,这问题原来也困扰了偶好久哈^_^
SendData=packed record
Command:string[5];
Content:string[255]; //不用数组服务器读不到,加上又不能完全发送,而且最大只能255
end;
如何修改?我的做法如下
Type
SendData=packed record
Command:string[5];
Content:array[0..1024] of char;
end;var SendData:TSendData;
begin
FillChar(SendData,SizeOf(SendData),0);
StrPCopy(@SendData.Command,'send');
StrPCopy(@SendData.Content,EdtMsg.Text);
IdTcpClient.WriteBuffer(SendData,SizeOf(SendData),True);
end;服务器端这样取
ShowMessage(StrPas(@SendData.Content));其他的答案大家分享下,比如使用PChar,Byte本人抛砖引玉,大家踊跃发言哈,这问题原来也困扰了偶好久哈^_^
解决方案 »
- 在delphi中怎么调用其他窗体的函数
- 请Delphi开发人员,有没有人来太原
- delphi7下使用vssConneXion的问题,寻Delphi7 Update Pack #1
- [请教]解决结贴,在线等!请大家帮忙看看!
- 如何按比例在image中画坐标大的点
- 请教:如何让delphi程序在不同语言环境下都能正常显示文字?
- 请问,怎样用编程方法实现tracert命令???
- 关于ActiveX Library的问题
- 学Delphi这么久了,还不知道不用IDE怎样编译Delphi程序??谁会啊?
- Delphi初学者的一些问题。
- 讨论delphi内存执行方法
- 类型抽象的问题...麻烦指点下,卡壳了....-_-!
procedure TAsyncTCPClient.Write(const Data: String);
var
FLen: Cardinal;
begin
FLen := Length(Data);
if Connected and (FLen > 0) then
try
inherited;
FIOHandler.WriteBufferOpen;
FIOHandler.Write(PACKET_SIG);
FIOHandler.Write(FLen);
FIOHandler.Write(Data);
FIOHandler.WriteBufferFlush;
except on E: Exception do
DoClose(E);
end;
end;
读取:
FCode := FIOHandler.ReadSmallInt();
if FCode = PACKET_SIG then
begin
FLen := FIOHandler.ReadLongWord();
if FLen > 0 then
Result := FIOHandler.ReadString(FLen);
if Length(Result) > 0 then
LogMessage('Receive: ' + Result);
所以用char,byte都行,Pchar存在跟长string一样的问题,根本不用考虑。
所以用char,byte都行,Pchar存在跟长string一样的问题,根本不用考虑。
所以用char,byte都行,Pchar存在跟长string一样的问题,根本不用考虑。
不用数组时传过去的是这边的地址,你让服务器上的string访问他自己的地址就不知道是啥玩意了。
SendData=packed record
Command: array[0..5] of char;
Content:array[0..1024] of char;
end;
应该是STRING的问题。
String[N],实际上是一个ShortString,它就只支持256个字节(含结束符在内)。
A ShortString is 0 to 255 characters long. While the length of a ShortString can change dynamically, its memory is a statically allocated 256 bytes; the first byte stores the length of the string, and the remaining 255 bytes are available for characters. If S is a ShortString variable, Ord(S[0]), like Length(S), returns the length of S; assigning a value to S[0], like calling SetLength, changes the length of S. ShortString is maintained for backward compatibility only. The Delphi language supports short-string types - in effect, subtypes of ShortString - whose maximum length is anywhere from 0 to 255 characters. These are denoted by a bracketed numeral appended to the reserved word string. For example, var MyString: string[100];
creates a variable called MyString whose maximum length is 100 characters. This is equivalent to the declarations type CString = string[100];
var MyString: CString;
Variables declared in this way allocate only as much memory as the type requires - that is, the specified maximum length plus one byte. In our example, MyString uses 101 bytes, as compared to 256 bytes for a variable of the predefined ShortString type. When you assign a value to a short-string variable, the string is truncated if it exceeds the maximum length for the type. The standard functions High and Low operate on short-string type identifiers and variables. High returns the maximum length of the short-string type, while Low returns zero.
Type
PSendData = ^TSendData;
TSendData = packed record
Command:string[5];
Content_len: Integer;
Content:[0..0] of AnsiChar;
end;
对于这个结构,看似Content只有一个字节,实际上当你采用动态分配的时候,它就可以有N(包括0)个字节。只是需要关闭编译器的越界检查。发送端var
Data: PSendData;
strContent: String;//注意:这里只说ANSI Code,如果是使用Unicode版本(Delphi2009)的,另议
begin
strContent := ... //这里数据任意
GetMem(Data, sizeof(TSendData) - 1 (*默认的一个字节*) + Length(strContent));
Data^.Command := 'Text';
Data^.Content_len := Length(strContent);
Move(strContent[1], Data^.Content[0], Length(strContent));
SendData(Data);
FreeMem(Data);
end;接收端var
Data: PSendData;
begin
AllocMem(Data, sizeof(TSendData) - 1 (*默认的一个字节*) );
RecvData(Data, sizeof(TSendData) - 1 (*默认的一个字节*) );
if Data^.Content_len > 0 then begin
ReallocMem(Data, sizeof(TSendData) - 1 (*默认的一个字节*) + Data^.Content_len);
RecvData(@(Data^.Content[0]), Data^.Content_len);
end;
ProcessCommand(Data);
FreeMem(Data);
end;
TPackageRec = record
Checker: integer; // 4 bytes 包起始标志
PackSize: integer; // 4 bytes 包尺寸
SerialNo: integer; // 4 bytes 包序号
case integer of
0: // Command Package;
( prCommand: Byte; // 1 bytes
PackType: Byte; // 1 bytes 包类型
WantAnswer: ByteBool; // 1 bytes 是否需要应答
CheckSum: Byte; // 1 byte 包校验
Parami: array [0..3] of integer; // 整型参数
Params: array[0..1023] of Char; // 数据
);
1: // Status Package;
( prStatus: Byte;
);
2: // ptData
( prData: Byte;
);
end;
PPackageRec = ^TPackageRec;
实际包数据不一定有1024字节,有多少算多少。
基本是数组的char或byte
Type
SendData=packed record
Command:string[5];
Content:string[255]; //不用数组服务器读不到,加上又不能完全发送,而且最大只能255
end;
如何修改?
//////////////////////
可以不用数组,但是这个结构就只有2个指针,所以发送的时候不能一次发送出去。
Type
SendData=packed record
Command:string;
Content:string;
end;
var SendData:TSendData;
begin
SendData.Command:='send';
SendData.Content:=EdtMsg.Text);
IdTcpClient.WriteBuffer(Pointer(@SendData.Command[1])^,Length(SendData.Command),True);
IdTcpClient.WriteBuffer(Pointer(@SendData.Content[1])^,Length(SendData.Content),True);
end; 接收端也要分别接收,或者一次全部接收到一个buffer中,分别赋值给command和content
a1=packed record
s1:string[100]
end
var
pa:array of a1;
begin
setLength(pa,sizeof(a1)*1000);
end;
PSendData = ^TSendData;
TSendData = packed record
Command:string[5];
Content_len: Integer;
Content:[0..0] of AnsiChar;
end; 由于Content只有一个字节,那么使用的时候要特别注意,可以GetMem一个足够大的空间,准备给这个数组溢出来使用。
不过弊端在于如果定义使用了类似 sdTmp:TSendData;那么sdTmp.Content的拷贝操作会溢出,导致覆盖sdTmp变量后面的数据空间,
从而程序异常,而这样的异常现象千奇百怪,很难调试,所以千万注意。使用中也可以不动态申请空间,用个固定的缓冲区来强制转换,可以把buf定义为全局变量,减少内存的申请以及释放。
buf:Array[0..Max_packet_len] of Char;
..........
Data:PSendData;.................
Data:=PSendData(@buf[0]);
Move(strContent[1], Data^.Content[0], Length(strContent));
IdTcpClient.WriteBuffer(pChar(@buf[0])^,len,True);
...........
SendData = record
Command :char[5];
Content :array[1..255] of char;
end;//发送
var
MySendData: SendData;
Buffer: array[1..1024] of char;
begin
CopyMemory(@Buffer[1],@MySendData,SizeOf(MySendData));
IdTcpClient.Socket.Send(Buffer,SizeOf(MySendData));
end;
//读取var
MyReadData: SendData;
begin
AThrea.ReadBuffer(MyReadData,SizeOf(MyReadData));
//...就可以处理了MyReadData.Command 定长的还是比较简单的,关键是
type
SendData = record
MyList: TList; //....麻烦了,在研究中
end;
LoginTime: Integer;
CBLogin: TCBLogin;
Buffer: array[1..2048] of Char;
BEGINCopyMemory(@Buffer[1], @CBLogin, SizeOf(CBLogin)); //buffer2开始写内容
ClientTCP.Socket.Send(Buffer, SizeOf(CBLogin));
END;