4
回答
Tcpclient如何做到接收数据完整?
开发十年,就只剩下这套Java开发体系了   

现在做一个Tcpclient接收数据,但是不完整,用了clientStream.CanRead && clientStream.DataAvailable这些属性,都不能完整接收,下面是我的接收代码

try
            {
                int timeout = 45000; //ms
                Stopwatch sw = new Stopwatch();
                StringBuilder completeMessage = new System.Text.StringBuilder();
                sw.Start();
                lock (lockObject)
                {
                    if (clientStream.CanRead && clientStream.DataAvailable)
                    {
                        byte[] readBuffer = new byte[bufferSize];
                        int numberOfBytesRead = 0;


                        // Fill byte array with data from ARCL stream
                        numberOfBytesRead = clientStream.Read(readBuffer, 0, readBuffer.Length);


                        // Convert the number of bytes received to a string and
                        // concatenate to complete message
                        completeMessage.AppendFormat("{0}", System.Text.Encoding.ASCII.GetString(readBuffer, 0, numberOfBytesRead));


                        sw.Stop();
                        if (sw.ElapsedMilliseconds >= timeout)
                            throw new TimeoutException();


                    }
                }
                return completeMessage.ToString();
            }
            catch (TimeoutException ex)
            {
                return null;
            }




举报
共有4个答案 最后回答: 2年前

你这些属性只是保证流是否关闭  具体读完与否 最好与客户端做个数据的约定

比较常见的思路 如  数据包头几个字节为长度域   让客户端上送时 前面加上这几个字节

服务端先接受长度域后  可以对后面数据做校验


tcp协议是面向字节流的,唯一可以判定完整的就是等服务器主动关闭连接(准确的说,应该由你的服务端提供判定完整性的方法),而没有数据读取只是你的程序把tcp缓冲区的数据读完了,不代表数据已经发完了。

推荐使用异步接收,只要你两个数据包之间有一定的间隔时间,一般可以接收完整的数据包,前提是你的数据包也不大。

也可以自定义结束码,判断是否收到结束码判断结束

--- 共有 1 条评论 ---
OSC首席过客服务器用TELNET协议的。服务器不是由我定的了,现在我想要什么数据,只能发什么命令过去,等待数据返回 2年前 回复

完整性,不代表接收完。

3楼办法可以!有个小小的短板就是,当单个包体太大的话,得拿到整个buffer才能解析处理。

还有一种方案,用xml,动态解析器。比如expat,即使xml不完整,也能解析。

--- 共有 1 条评论 ---
OSC首席过客我的设备是使用TELNET登陆,然后根据需求发送相关命令,然后接收数据,什么样的格式数据,不是由我定义了。这是一个设备,已经定了的东西,我修改不了的 2年前 回复
顶部