为何SOCKET接收到PCHAR类型数据无法读取?(10分)

  • 主题发起人 主题发起人 dazzling
  • 开始时间 开始时间
D

dazzling

Unregistered / Unconfirmed
GUEST, unregistred user!
我的socket读事件中有:
socket.ReceiveBuf(SI,sizeof(si));
其中SI是一个数据结构,有一个类型为pchar的成员apps,
则操作:
s:=strlen( SI.apps);
或 p:=SI.apps //p已定义为pchar类型
或 Memo1.Line.SetText(SI.apps)
均报内存错误!到底如何读取呢?谢谢各位!
 
.............
getmem(SI.apps,1024);//分1K的内存,你分多少自己看着办吧
socket.ReceiveBuf(SI,sizeof(si));
Memo1.Line.SetText(trim(SI.apps));
freemem(SI.apps);
.............
 
仍然出错如前。
行到这行:
Memo1.Line.SetText(SI.apps);
出错,若注释掉它则
freemem(SI.apps);
行出错。
 
一日一顶
Feb24
 
看看你的SI结构头,和如何定议的
 
看看你的
SI结构定义的!另外告诉你用 GetMem分配内存时应该这样
PA = ^TA
TA= Record
a : integer;
end;
//----------------------------
var
a : PA;
//----------------------
为A分配内存时要这样
GetMem(a,sizeof(TA)); 如果用 GetMem(a,Sizeof(a))或GetMem(a,sizeof(PA))
则在访问指针时,都会出内存地址错误!要不用 new(a)也行
 
SI头定义:
type

TSYSINFO = record
company:string[20];
pcname:string[20];
ip:string[20];
cpu:string[4];
ram:string[10];
hd:string[10];
win_user:string[20];
os:string[100];
user:string[20];
dept:string[10];
pc_id:string[20];
pc_asset:string[20];
status:string[100];
apps:pchar;
end;
 
一日一顶
Feb28/06
 
type

TSYSINFO =packed record
company:array[1..20] of char;
pcname:array[1..20] of char;
.......
apps:pchar;
end;
 
调调你啊
strpas行不?
 
很定错误,你知道pchar是个指针,
socket.ReceiveBuf传递过去就是app在A计算机上的地址,
到B计算机读取这个地址的内容,肯定出现错误。
比如app的内容是'1111',但地址是0X00001,
你现在在B计算机读取0X00001的值,肯定错误。
 
sizeof(si);当中pchar=4,不是你的值得长度。

具体解决办法,自己搞定.
 
正在开发电信SMGP协议数据包:
我是这样实现的:
1、首先定义
 Buffer=array [1..8192] of char;
2、声明变量 ReceBuf :Buffer
3、接收数据 Socket.ReceiveBuf(ReceBuf, BufLen)
4、解包
解开Integer型数据域
function GetIntFromBuf(Buf:buffer;var Start:LongWord):longWord;
begin
//高位在前
Result:=ord(Buf[Start])*16777216+ord(Buf[Start+1])*65536+ord(Buf[Start+2])*256+ord(Buf[Start+3]);
Start:=Start+4;
end;

解开String型数据域
function GetStrFromBuf(buf:Buffer;var start:LongWord;Const String_len:Byte):string;
var
ppGetStr:pchar;
i:longword;
psStr:string;
begin
//变长
{ ppGetStr:=@buf[start];
start:=start+length(ppGetStr)+1;
result:=ppGetStr;}
//定长
SetLength(psStr,String_len);
for i:=1 to String_len do
psStr:=buf[Start+i-1];
ppGetStr:=@psStr[1];
start:=Start+String_len;
Result:=ppGetStr;
end;

仅供参考,希望对你有所帮助。
 
这里为什么要用PChar?
接收的数据是怎样定义的?
这样直接往结果里写入,apps里不会有任何有意义的值,因为你总不会用Socket传指针吧。
如果apps是一个长度不确定的字符串,那就应该在结构里加上一个字段表示apps的长度。
然后接收的时候先读取长度数据,然后根据长度分配内存。
还有,把PChar当作字符串使用的时候应该强制转换String(apps)
 
之所以用PCHAR传,因为长度不定。
PCHAR是不是真的无法传输?如果可以,应如何做?我接收时甚至长度为1都错误。
如果不行,用什么代替来传输不定长数据??
 
怎么可能直接用SI结构来接收呢?????
你直接用一个buff来接收
然后再填充到SI结构apps中
sizeof(si)
也可以直接改成
Socket.ReceiveLength()
 
偶正是不知道如何将BUF填充到SI结构中呢。。。。。
 
利用内存操作
copymemory(@tmp,pchar(H2head),86)
ss:=Socket.ReceiveText;
//FillChar(buf1,sizeof(buf1),' ');
//Socket.ReceiveBuf(buf1,86);
//ss:=strpas(@buf1);
 
我认为你的思路有问题,按照你的思路,接收方怎么知道应该接收多少个字节的 Buffer 呢?例如:发送方发送的数据中 Apps 为 100 Byte 的数据,但是没有任何地方标示出此长度,那么接收方接收到多少 Byte 认为接收完毕了呢?你可以将实际发送的数据大小作为发送包的一个信息项,这样接收方就可以知道应该接收多少字节的数据了,这里说的包可不是你的 Record 噢。
例:一个发送包的结构:[包头] + [包长] + [数据(你的Record)] + [包尾]
接下来就可以使用指针将数据复制到你的 Record 对象中了。
 
后退
顶部