您的位置:程序门 -> delphi -> 网络通信/分布式开发



关于udp传输的结构体中string长度


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


关于udp传输的结构体中string长度
发表于:2008-01-13 16:32:22 楼主
关于udp传输的结构体中string长度

type
    txtdata=record
    cmd:string;
    s:string;
end;

xt:txtdata;

idudpserver1.sendbuffer(serverip,1001,xt,sizeof(xt));
     

谁能解决他的长度问题   不喜欢多包   不太容易控制     不喜欢规定他长度   最大254不够用   谁给个最佳解决方案
发表于:2008-01-13 18:13:001楼 得分:0
这样干不行吧,sizeof长度肯定不对,要用数组

type
        txtdata=record
        cmd:array[1..24]   of   char;
        s:array[1..1024]   of   char;
end;  
发表于:2008-01-13 18:52:552楼 得分:0
我是想这样不限制长度   不是行不行   我原定义的是s:string[254];

1024也不够用  
发表于:2008-01-13 18:54:023楼 得分:0
必须让大小动态   要不封包大小浪费资源的
发表于:2008-01-13 18:59:434楼 得分:0
没看明白delphi的idudp中的send()怎么构造string特别长的
发表于:2008-01-13 20:07:595楼 得分:0
可以继续使用这种定义:
type
        txtdata=record
        cmd:string;
        s:string;
end;  

只是需要自己写一个打包过程而已。

function   packdata(const   data:   txtdata):   string;
var
    n1,   n2:   cardinal;
begin
    n1   :=   length(data.cmd);
    n2   :=   length(data.s);
    setlength(result,   sizeof(n1)   +   n1   +   sizeof(n2)   +   n2);
    move(n1,   result[1],   sizeof(n1));
    move(txtdata.cmd[1],   result[sizeof(n1)   +   1],   n1);
    move(n2,   result[sizeof(n1)   +   n1   +   1],   sizeof(n2));
    move(txtdata.s[1],   result[sizeof(n1)   +   n1   +   sizeof(n2)   +   1],   n2);
end;

然后
idudpserver1.send(serverip,1001,   packdata(xt));  

接收端需要一个解包过程,大同小异,你自己写吧。:)
发表于:2008-01-13 20:25:326楼 得分:0
太晚了   谢谢了   明天早上试试看   还有什么解法大家都说说   完事散分
发表于:2008-01-13 21:03:467楼 得分:0
如果不定长,需要在协议内定义各块数据长度,5楼方法可行。
即:不定长部分需要把包长度也放在传输数据里,接收端首先解析数据块长度,然后再读取对应长度的数据。
发表于:2008-01-13 21:15:108楼 得分:0
补充一下,建议报命令采用   cardinal   类型,这样处理包命令简单。
如:
const
    cmd_login   =   $00000001;
    cmd_logout=   $00000002;
...
type
        txtdata=record
        cmd:   cardinal;
        s:   string;
end;  

function       packdata(const       data:       txtdata):       string;
var
    len:   cardinal;
begin
        len   :=   length(data.s);
        setlength(result,sizeof(cardinal)+len);
        move(data.cmd,result[1],sizeof(cardinal));
        move(len,result[sizeof(cardinal)+1],sizeof(cardinal));
        move(data.cmd[1],result[sizeof(cardinal)*2+1,len);
end;  
发表于:2008-01-14 02:33:469楼 得分:0
不对   我不是要send出一个string
我是要sendbuffer一个包含n个string类型n(未知数)长度的结构体啊   不能局限在254啊  
发表于:2008-01-14 08:33:3710楼 得分:0
udp是有包长限制的,过大的udp包,有可能收不到,或者严重丢包。
楼主提到的返回string并不是不能使用sendbuffer.
delphi(pascal) code
var strsend:string; strsend := packdata(xt); sendbuffer(ip, port, pchar(strsend)(*这里面根据需要,具体看参数,如果不是pchar类型,而可以用pchar(strsend)^或者strsend[1]代替*), length(strsend));
发表于:2008-01-14 09:20:2511楼 得分:0
不管你定义多大的包,最好的做法还是在包头部记录整个包的长度,因为你收到时会有包粘连的情况,你分隔后最后的一个包可能让断开了,要在下一次收到时进行合并。
发表于:2008-01-14 11:23:5412楼 得分:0
不管你定义多大的包,最好的做法还是在包头部记录整个包的长度,因为你收到时会有包粘连的情况,你分隔后最后的一个包可能让断开了,要在下一次收到时进行合并。

完全胡说。

udp   没有所谓的粘包问题,     udp   最大长度65535-   iphead     不超过这个长度,网络够通畅,   对方的接受buff   够大就可以收到了。ip层会自动把分片后的数据合并,不必担心。
发表于:2008-01-14 14:18:5213楼 得分:0
send   返回的值应该是指发送的长度吧.   就是说   send('1234567890')可能返回5,即只发送了5个字节的数据出去,其它有没有发送成功.

当你在调用send   的时候windows会将内容保存在一个缓冲区中,如果你发送的足够快,就会发让缓冲区满了,
假设缓冲区的大小是1000个字节,连续发送每次300字节,第四次就只发出去了100字节.返回值就是100

收的时候,可能收到了多个数据但只有一次receive事件.

至于最下层的发送分片是在读取了缓冲区后在发送时进行的,是更低层的驱动完成的.

当然我们很多情况下发送时
for....
begin
send();
sleep(1000);
end

这样完成的,要是将sleep去掉,有很大机率会出现一个receive事件收到多个包和send   时有部分数据没有发送.
发表于:2008-01-14 14:33:0514楼 得分:0
不管你定义的结构中有多少个串或者其他类型,都可以打包到一个string中。
delphi的string可以存任意数据,最大可以到2gb(32-bit下),可以直接当buffer来使用。
发表于:2008-01-14 17:57:0215楼 得分:0
说什么呢   一个解决方案也没有   赶上作总结了

type  
        txtdata=record  
        cmd:string;  
        s:string;  
end;  

xt:txtdata;  

idudpserver1.sendbuffer(serverip,1001,xt,sizeof(xt));  

大家别管udp报最大多大   这个技术我有解决方案

我问的是我的结构体中string不能固定再254   太小   不采用多包的情况下解决这个问题   记住是sendbuffer     别整到send(string)去   这个send是笨鸟才用的  
发表于:2008-01-14 18:01:2516楼 得分:0
大家帮想想最简便最佳的解决方案   从结构上   从发送接收上
发表于:2008-01-14 18:13:0417楼 得分:0
还有我传的是结构体   不是一个单独的string   服了喲
发表于:2008-01-14 18:17:4218楼 得分:0
笨鸟,不是都告诉你了吗?:)
send就是调用sendbuffer实现的,两者没有本质的区别。
你非要用sendbuffer,假设s是string,s[1]就是buffer的首地址。
发表于:2008-01-14 18:24:5319楼 得分:0
我传的是结构体   我的产品源码结构体不是上面代码那么简单的   老send什么   有毛病啊   我要解决string长度问题   你老提那个做什么
发表于:2008-01-14 18:26:2720楼 得分:0
我用简单的代码来问问题   不展露产品复杂的结构源码   老让我send什么   答非所问   有毛病
发表于:2008-01-14 18:30:4221楼 得分:0
能解决问题的来   不用你们分析   怎么回事俺这么多经验俺明白   混分的别来
发表于:2008-01-14 18:31:2522楼 得分:0
不行就得写个烦人的处理过程了   埃
发表于:2008-01-14 18:37:5523楼 得分:0
我混你那几分?好笑。
不管你的结构多复杂,都可以打包到一个buffer中,至于这个buffer用string、array还是getmem一块空间,都是一回事,没有本质的区别。
你要实现不固定大小的动态结构,就肯定要采用类似的方法,就我所知,目前还没有哪种语言支持你想要的那种结构。
你既然“这么多经验”,连这么简单的问题都解决不了吗?:)
发表于:2008-01-14 19:25:2324楼 得分:0
不用你讲这些   我都知道   我问的是有没有解决string长度方法   你还听不懂人语   你心里有问题   说话满斗气的
发表于:2008-01-14 19:25:5525楼 得分:0
有病的人
发表于:2008-01-14 19:27:2826楼 得分:0
解决不了这个还开发通信产品   你脑袋也不想想   只是寻求一种死的方法   神经病   爱斗气回家和你妈斗去
发表于:2008-01-15 12:03:5327楼 得分:0
楼主的态度有问题,请将注意力放在解决问题上面,大家都是冲着帮你解决问题的态度来的,

---------------------------

首先基础概念就有问题,   象这样的定义,不明白你怎么能传递的对???
delphi(pascal) code
type txtdata=record cmd:string; s:string; end; xt:txtdata; idudpserver1.sendbuffer(serverip,1001,xt,sizeof(xt));


string根本上来说只是一个指针,一个指针是4   个字节长度,所以你的   sizeof(xt)在32位的计算机上永远都是8

sendbuffer   只是传递一个连接的内存块,不管你里面保存的是什么,当然要给定的是起始的位置和传递的字节数.

string   是delphi   自己定义的数据类型,而socket通信都是接字节来传递的,所以要用socket最好用字符串数组
如果你的接受端不是delphi开发的,最好在定义结构的时候加上pack   record
用结构体来保存要传递的数据只是方便你赋值操作罢了,对于一些变长的传递会不好操作.最好的办法是用一个对象封装,
delphi(pascal) code
txtdata=record private fid:string; ftitle:string; public function getdata(var ap:pointer):integer; published property id:string read fid write fid; property title:string read ftitle write ftitle; end; //得到值的指针和长度,注意,用完后要释放ap function txtdata.getdata(var ap: pointer): integer; var acmd:string; astr:string; pint:pinteger; len:integer; xd:txtdata; begin len:=length(fid)+length(ftitle)+sizeof(integer)*3; ap:=getmemory(len); pint:=ap; pint^:=len; //保存总长度 pint:=pointer(integer(pint)+sizeof(integer)); pint^:=length(fid); //保存第一个字符串长度 pint:=pointer(integer(pint)+sizeof(integer)); copymemory(pint,@fid[1],length(fid));//保存第一个字符串内容 pint:=pointer(integer(pint)+length(fid)); pint^:=length(ftitle); //保存第二个字符串长度 pint:=pointer(integer(pint)+sizeof(integer)); copymemory(pint,@ftitle[1],length(ftitle));//保存第二个字符串内容 // freememory(ap); result:=len; end; //从收到的值中恢复 procedure txtdata.setdata(const ap: pointer; len: integer); var pint:pinteger; i:integer; xd:txtdata; begin pint:=ap; // len:=integer(pint); copymemory(@xd,ap,len); i:=pinteger(pint)^;//得到总长度 pint:=pointer(integer(pint)+sizeof(integer)); i:=pinteger(pint)^;//得到第一个字符串长度 setlength(fid,i); pint:=pointer(integer(pint)+sizeof(integer)); copymemory(@fid[1],pint,length(fid));//得到第一个字符串内容 pint:=pointer(integer(pint)+length(fid)); i:=pinteger(pint)^; setlength(ftitle,i);//得到第二个字符串长度 pint:=pointer(integer(pint)+sizeof(integer)); copymemory(@ftitle[1],pint,length(ftitle));//得到第二个字符串内容 end;

发表于:2008-01-15 16:21:3928楼 得分:0
楼主,你都知道?你知道个鸟!
从你9楼的发言你是个什么水平大家也都看出来了。
就你这种自以为是的态度+一个不开窍的榆木脑袋,你是彻底没前途的。
早告诉你了,结构中的成员要不固定大小和位置,只能先打包到一个buffer中再发送,至于这个buffer用string、array还是getmem一块空间,都是一回事,没有本质的区别。   没有你异想天开的那种自适应record类型。
听懂了没有?
真是个tmd毫无灵气、冥顽不化的笨鸟。:)


另,to   zyxip,
在record中private是无效的,所有成员仍然能从外部直接访问。
就这个笨蛋的问题来看,除了在发送前动态建立结构,也没什么更好的办法,要不就是定义一个足够大的固定结构+压缩发送。
发表于:2008-01-15 16:56:2829楼 得分:0
你知道个鸟   我什么水平关你鸟事   你他妈的   我寻个string的死点子你他妈的老强调你妈的毛你的方法   这就看出我的水平?   你真不要脸

另外谢谢zyxip  
发表于:2008-01-15 16:57:2330楼 得分:0
我就爱钻研这个srting的牛角尖我就不爱用别的类型   你他妈的老放屁毛
发表于:2008-01-15 17:16:5031楼 得分:0
txtdata=record  

这个是写错了。应该是   txtdata=class  
发表于:2008-01-15 17:44:1032楼 得分:0
楼主,你造的“笨鸟”这个自我评价实在是太恰当了。
很久没见到你这么笨还又臭又烂的榆木脑袋了,我玩定你了,你别想跑。:)
发表于:2008-01-15 17:51:5933楼 得分:0
笨鸟,你懂不懂打包到string也能用sendbuffer呀?
10楼都给你讲解了,你还是榆木脑袋死不开窍,是不是你妈怀孕的时候吃了死老鼠才生出你这么个钝胎来?
也不知道哪家倒霉的公司用你这种垃圾开发“通信产品”?
哈~~~哈~~~哈~~~哈~~~哈~~~

发表于:2008-01-15 18:56:2734楼 得分:0
傻b   大包到string对我没用   你老提你屁话干嘛   这样方法对我的产品没用你老讲个鸡巴
发表于:2008-01-15 18:57:5635楼 得分:0
你的脑袋榆木   笨的傻b老叫什么   我倒霉?哪个公司有你不是要倒闭了   可笑的东西

另外感谢zyxip  
发表于:2008-01-15 18:59:0036楼 得分:0
话都听不懂   还他妈的混呢   可笑
发表于:2008-01-15 19:00:2437楼 得分:0
发表于:2008-01-15   17:44:1032楼   得分:0  
楼主,你造的“笨鸟”这个自我评价实在是太恰当了。  
很久没见到你这么笨还又臭又烂的榆木脑袋了,我玩定你了,你别想跑。:)    


一看你这种人很臭的那伙的
发表于:2008-01-16 16:53:2038楼 得分:0
笨鸟,现在学会一点技术了吗?
教你这种不开窍的榆木脑袋还真是不容易。
对你没用啊,那你现在学会动态创建不定长的结构没有?
哈   哈   哈   哈   哈   ...
废柴。
发表于:2008-01-16 16:57:4939楼 得分:0
我不用动态创建不定长的结构   你老哇哇叫什么   菜鸡
发表于:2008-01-17 16:26:4040楼 得分:0
哈       哈       哈       哈       哈       ...  
笨鸟,又自相矛盾了不是。
你“不用动态创建不定长的结构”,那你还问个嘛???
吃屎了?


快速检索

最新资讯
热门点击