一个socket发送数的问题???有通讯方面的高手请进来指教一下、 ( 积分: 50 )

  • 主题发起人 主题发起人 hjp0214
  • 开始时间 开始时间
H

hjp0214

Unregistered / Unconfirmed
GUEST, unregistred user!
有个长度为324的十进制数,想通过buffer:array[0..1023]of byte 数组传送,
对方要求只是两个字节。例如:FF FF--》255 255 对应的十进制数65535。
那么怎么把324十进制数赋值给数组的两个值,就是buffer[0] := ?? Buffer[1]
:= ??.能代表324的十进制数,好像要用什么BCD码,请帮忙??
 
有个长度为324的十进制数,想通过buffer:array[0..1023]of byte 数组传送,
对方要求只是两个字节。例如:FF FF--》255 255 对应的十进制数65535。
那么怎么把324十进制数赋值给数组的两个值,就是buffer[0] := ?? Buffer[1]
:= ??.能代表324的十进制数,好像要用什么BCD码,请帮忙??
 
高位取整,低位取余就可以哪1
 
dxwleaf:能不能具体点。给一些代码参考,谢谢
:
 
我看你的问题是不是 怎么把十进制 324 转换成 十六进制
buffer[0]:= $FF;

buffer[0]:= 255;
有区别吗!!
 
这个是大数问题啊`` 研究生作业里面 老师布置过这个问题
不记得怎么弄的了 哈
 
把它当成255进制不就好了。
通讯的话主要还是看双方的约定
 
不是长度为324吧!而是=324;
如为压缩BCD码(2位BCD),换成HEX码:
03H 24H;

如果不要求BCD,就直接取;
高位:=HiByte(324);
低位:=LoByte(324);
超过65535的数没法存吧,所以原变量用WORD;(或对65536取模);

******************************************************
再仔细看了一下,建议你用第一种BCD码,转成字符串2位一存;
但接收方收到后单字节BUFFER必须要转回到10进制;
如18(12H)实为12;

转BCD码是协议安全问题;
两边都要转换,最简单位的是就用十进制:
先转成字符串,2位取,再转成BYTE(不可能超过99了);
你这个数也太大了:LongINT也放不下吧;
或者开始就是字符串?
设为Str1;
Type
Tbuffer1:array[0..163]of byte; //324 div 2 +1
Fuction StrToBuf(Str1:String;var Buf1:Tbuffer1):boolean;
var
i,len:Word;
begin
len:=Length(Str1);
if Len>324 then
begin
result:=False;
exit;
end;
//前2字节为长度;
Buf1[0]:=HiByte(len);
Buf1[1]:=LoByte(len);
try
if len Mod 2=0 then//长度为双数
begin
for i:=0 to (Len div 2)-1 do
buf1[i+2]:=StrtoInt(copy(Str1,i*2+1,2));
end else//长度为单数
begin
buf1[2]:=StrtoInt(copy(Str1,1,1));
for i:=1 to (Len div 2)-1 do
buf1[i+2]:=StrtoInt(copy(Str1,i*2,2));
end;
except
result:=False;
exit;
end;
Result:=true;
end;
 
通讯协议,报文内容
SIM卡号码 N_STRING 11
一卡通指令号 CHAR 1 ‘B’表示为黑名单版本
版本号 H_STRING 4
名单长度 H_STRING 2 最大数FFFFH
而得到名单长度值=324,那么delhiphi怎样用两个字节表示呢。最大数FFFF,也就是十进制数的65535了,十进制数324 --->十六进制144
 
HIBYTE(324)或者324 Div 256;
Lobyte(324)或者324 mod 256;

如要转BCD有现成的函数:
function DigitalTran(number1:longint;InDig,OutDig:Byte):longint;
var
midval,hexx : longint;
Begin
midval:=0;
hexx:=1;
repeat
midval := midval + (number1 mod OutDig)*hexx;
number1 := number1 div OutDig;
hexx := hexx*InDig;
until number1 =0 ;
result:= midval;
end;
还有什么地方不明白?
 
To jlyin:
Buff[0] :=1;
Buff[1] :=68;
那么怎样才能得到以前的十进制数324呢
 
1*256+68=324!
另外,用SOCKET还可直接用字符串通讯,
socket1.sendtext(...);
 
发送字符,很浪费传输空间的,我们都使用压缩BCD码,谢谢jlyin,
 
结分吧,你这个不是压缩BCD码;
压缩BCD码是324:
Buff[0]:=$3;
Buff[1]:=$24;//36
 
SendText 可以发送任何内容
SendText(Chr(324 mod 256)+Chr(324 div 256));
 
怎样处理Socket传送大于4096的数据问题.
现在客户端是这样处理的:
procedure TfrmClient.ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
iPackageSize: Integer;
TempBuf: ByteArray;
begin
while socket.ReceiveLength>0 do
begin
iPackageSize := socket.ReceiveLength;
FillChar(TempBuf,length(TempBuf),0);
Socket.ReceiveBuf(TempBuf,iPackageSize);

TranMemBuf(TempBuf,iPackageSize);//解析报文过程
end;
end;

socket.ReceiveLength>8192
服务端是多线程的,不断向客户端发送数据.
感觉到socket.ReceiveLength=0后才能处理报文解析.这样很容易缓存区溢出.
不知道有什么好办法处理???
 
1、两个字节发送324没又那么复杂
var
data:word;
data:=324;
Socket.sendBuf(data,2);
2、接收不能以ReceiveLength来判断,你的发送方应该将报文长度先发过来,然后接收方根据这个长度接收指定长度就是一个完整的报文了阿
 
如果客户端与服务端平台一样,即机器字长一样,字节次序一样,只要用move函数就可以
即:
var
i : Integer
Begin
i := 324;
move( i, buffer[0], sizeof(Integer) );
socket.sendbuf( buffer, 1024 );
End;

接收端收到后
move( buffer[0], i, sizeof(Integer) );
发送端的i是多少,接收端就是多少。

如果是跨平台发送,建议用XML方式,否则必须转换字节次序。
 
kk365,:
要发送的不仅仅是长度324,还有其他字符串的.整个报文包括报文长度和报文内容.
所以单独发324是没有必要的,还要报文内容一起组合发送.
 
你把报文内容再move进buffer就是了嘛。比如你的报文内容是一个串str, 只需
move(str[0], buffer[sizeof(integer)], Length(str) )
有什么东西往buffer里填就是。(所以是buffer[sizeof(integer)], 是假定了在长度之后就是报文内容的串str, 就是说前四个字节是报文长度i,(整型是4个字节,如果你的长度是两字节,将i的类型改为Word,并且sizeof(word)),然后就是报文串)
 
后退
顶部