基于TCP协议,socket传输部分乱码问题。

Salted-fish 2018-03-06 05:11:33
实现代码
OutputStream out = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(out);

//写入波形
int[] data = packet.getDatas();

dos.writeInt(convertInt(data.length * 2));//波形长度 int=4字节

dos.writeInt(convertInt(packet.getUserString().getBytes().length));//病人信息长度

for (int i : data) {
dos.writeShort(convertShort((short) i));
}
//写入病人信息
byte[] bs = packet.getUserString().getBytes(Charset.forName("Utf-8"));
for (byte b : bs) {
dos.writeByte(b);
}
dos.flush();
packet是1个自定义的实体类里面有 private int[] datas;//波形 private String userString;//用户json
传输的是两个数据包。convertShort方法是高低位字节互换
然后出现部分乱码


传输的数据格式应该没错。我初步怀疑是两个包1起传,出现了粘包,拆包问题。因为其他不需要传包和传1个包的请求就不会乱码。但是我传输这两个包之前都先传输了包的长度信息。没用吗。
...全文
2228 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
ljh8698 2019-01-17
  • 打赏
  • 举报
回复
感谢前辈,鄙人新手,很有收获!!!
Salted-fish 2018-03-16
  • 打赏
  • 举报
回复
不知道是否是设备系统不1样,导致文件长度变化了。但我经理说都是2进制文件,不可能变化。
Salted-fish 2018-03-16
  • 打赏
  • 举报
回复
后续解决方案我也会继续更新的。
Salted-fish 2018-03-16
  • 打赏
  • 举报
回复
问题终于解决了,发现是接收波形的时候。波形文件的长度是前端传过来的。因为是不同设备传输上来的文件。发现其中1种设备传输的文件长度和文件上传到linux服务器的实际长度不1致,导致另1个公司根据我发送的波形文件长度读取。波形数据文件丢失字节。然后导致后面的接收内容对不上号。出现乱码。目前只是做了个判断,如果文件的长度跟实际传输到服务器的文件长度不1致,就不发送。后续准备专门做1个这种设备上传的HTTP。
xiaopi224 2018-03-11
  • 打赏
  • 举报
回复
这个东西发送端控制不了的,接收端根据长度信息解析即可。
Salted-fish 2018-03-09
  • 打赏
  • 举报
回复
那这种乱码,有可能是网络波动,丢包造成的吗?
X-i-n 2018-03-07
  • 打赏
  • 举报
回复
你做发送端那就省事了,协商好结构,无脑发就行。剩下的交给对方去处理,那是他的事。 flush我不确定管不管用,你可以试试。我的理解是,它只是将这个流的缓冲区(JAVA)的内容送给了更底层的socket(操作系统),而socket本身的行为你控制不了。不过你可以给socket加上nodelay参数。 另外,我建议你找接收方让他们做好数据的完整性判断,如果对方需要修改数据结构方便做识别,再由你去配合对方。因为即使用flush“极大地”改善了这种情况,而不是“完全解决”你的问题,那也是毫无意义的。SOCKET本身不光有粘包问题,还有分包问题。所以你需要的是一个能够精确无误地将这些包还原出来的可靠算法,而不是碰运气。
Salted-fish 2018-03-07
  • 打赏
  • 举报
回复
最笨的解决办法,我把int []data传完之后,加个flush。再传byte[] bs 。 就是两个包之间先flush下。是否能解决粘包问题。如果能解决传输速率是否会大大降低还是微乎其微。
Salted-fish 2018-03-07
  • 打赏
  • 举报
回复
因为是实时传输,所以用socket比较快。
Salted-fish 2018-03-07
  • 打赏
  • 举报
回复
我这是把我公司的数据传给另1个公司,我做的发送端的。
X-i-n 2018-03-06
  • 打赏
  • 举报
回复
粘包没有什么好办法,只能自己解析。先把stream里读出来的内容存到buffer,再按定义好的数据结构去查有没有包含尾串(你的场景里是json,判断尾串的办法不适用,不过也有讨巧的办法,逐字符追到临时字符串,碰到 } 时反序列化,直到成功为止算一条记录,此时保存,继续往下处理。),或者接收到长度以后按指定长度保存内容,够了就截断。另一种规避粘包的办法需要动到底层架构设计,用http当服务端就完全不用考虑粘包和分包。看哪种更符合你的需求吧。
Salted-fish 2018-03-06
  • 打赏
  • 举报
回复
这是1条信息
目录 第1章 Delphi网络编程基础知识 1.1 TCP/IP 1.1.1 TCP/IP结构 1.1.2 应用层协议 1.1.3 传输协议 1.1.4 网络层协议 1.1.5 RFC和标准简单服务 1.2 TCP/IP基本概念 1.2.1 IP地址 1.2.2 地址解析 1.2.3 域名系统 1.2.4 数据包的封装和分用 1.2.5 端口号 1.3 网络编程接口(Winsock API) 1.4 Winsock常用函数介绍 1.4.1 基本Socket函数 1.4.2 数据库函数 1.4.3 Winsock规范提供的扩展函数 1.5 Delphi Socket网络组件介绍 1.5.1 ClientSocket组件 1.5.2 ServerSocket组件 第2章 基本网络编程实例 2.1 获取IP地址 2.1.1 利用系统工具获得IP地址 2.1.2 使用GetHostByName函数来获取IP 2.1.3 使用WSAAsyncGetHostByName函数获取IP地址 2.1.4 多IP情况的处理 2.1.5 关于IP地址和实际的地址的区别 2.2 获取子网掩码 2.2.1 Windows NT系统中获取子网掩码 2.2.2 Window 9x系统中获取子网掩码 2.3 获取计算机名 2.3.1 获取和设置本机主机名 2.3.2 获取远程主机名称 2.4 网络连接情况检测 2.4.1 使用WinInet高级函数库函数检测网络状态 2.4.2 通过读取系统状态参数检测网络状态 2.5 获取DNS信息 2.5.1 Windows NT系统中获取DNS信息 2.5.2 Windows 9x系统中获取DNS信息 2.6 网卡信息的获取 2.6.1 使用GUID获取网卡地址 2.6.2 NetBIOS来获得MAC地址 2.6.3 使用RPC方式获得MAC地址 第3章 FTP高级编程 3.1 FTP简介 3.2 安装设置FTP服务器 3.3 使用Windows内置FTP程序 3.4 深入FTP协议 3.4.1 FTP命令大全 3.4.2 FTP工作模式 3.5 开发FTP程序的方法 3.6 API开发高级FTP客户端程序 3.6.1 建立工程项目 3.6.2 关键代码分析 3.7 开发FTP服务器 3.7.1 建立工程项目 3.7.2 关键代码分析 第4章 HTTP高级开发 4.1 HTTP协议基本知识 4.1.1 HTTP背景 4.1.2 HTTP的内容 4.1.3 消息(Message) 4.1.4 请求(Request) 4.1.5 响应(Response) 4.1.6 访问认证 4.1.7 URL编码 4.1.8 HTTP协议的应用 4.2 开发文件下载程序 4.2.1 建立工程项目 4.2.2 关键代码分析 4.2.3 技术要点分析 4.3 HTTP API高级开发 4.3.1 控件介绍 4.3.2 关键代码分析 4.3.3 关键技术分析 4.4 Web Server高级开发 4.4.1 Web Server的基本理论 4.4.2 建立工程项目 4.4.3 关键代码分析 4.4.4 Web服务器的扩充 4.5 Web代理服务器的实现 4.5.1 代理服务器介绍 4.5.2 IE中使用代理服务器设置 4.5.3 建立工程项目 4.5.4 关键代码分析 第5章 Telnet高级编程 5.1 Telnet简介 5.2 使用Windows的Telnet程序登录远程服务器 5.3 深入Telnet协议 5.3.1 NVT ASCII字符集 5.3.2 Telnet命令 5.3.3 协商选项 5.3.4 子协商选项 5.3.5 Telnet操作方式 5.4 BBS客户端高级开发 5.4.1 建立工程项目 5.4.2 关键代码分析 5.5 Telnet代理服务程序实现 5.5.1 建立工程项目与关键代码分析 第6章 E-mail协议及高级编程 6.1 SMTP及发送电子邮件 6.1.1 SMTP的模型描述 6.1.2 SMTP的会话过程 6.2 POP3与接收电子邮件 6.2.1 POP3的模型描述 6.2.2 POP3的会话过程 6.3 信件结构详述 6.3.1 RFC822信件的格式和内容 6.3.2 构造符合RFC822的信件 6.3.3 RFC822信件的语法分析 6.4 MIME编码解码与发送附件 6.4.1 RFC822的局限 6.4.2 UUENCODE编码与解码 6.4.3 MIME及其编码 6.4.4 构造MIME信件 6.4.5 MIME信件的语法分析 6.5 E-mail乱码 6.5.1 乱码的常见形式及形成原因 6.5.2 避免乱码的方法 6.6 E-mail程序开发 6.6.1 建立工程项目 6.6.2 关键代码分析 第7章 网络监控、流量统计与资源搜索 7.1 网络流量统计 7.1.1 建立工程项目 7.1.2 关键代码分析 7.2 网络连接监控 7.2.1 建立工程项目 7.2.2 关键代码分析 7.3 网络配置和统计的使用实例 7.3.1 建立工程项目 7.3.2 关键代码分析 7.4 局域网资源搜索 7.4.1 建立工程项目 7.4.2 关键代码分析 7.4.3 关键技术分析 第8章 Modem串口通信编程 8.1 Modem的基础知识 8.1.1 Modem状态 8.1.2 AT命令 8.1.3 S寄存器 8.1.4 Modem返回信息码 8.2 SPComm通信控件 8.2.1 SPComm控件的属性 8.2.2 SPComm控件的方法 8.2.3 SPComm控件的事件 8.3 Windows串口通信编程 8.3.1 Windows通信API和串口通信 8.3.2 打开和关闭串口 8.3.3 串口配置和串口属性 8.3.4 读写串口 8.3.5 通信事件 8.3.6 设备控制命令 8.4 ASCII控制字符 8.5 Modem文件传输应用实例 8.5.1 建立工程项目 8.5.2 关键代码分析 第9章 拨号网络编程 9.1 RAS客户机 9.2 建立拨号连接 9.3 使用RAS(远程访问服务) 9.3.1 用系统电话簿进行拨号 9.3.2 电话簿条目的管理 9.3.3 在程序中创建拨号连接 9.3.4 状态通知 9.4 RAS高级开发拨号程序 9.4.1 创建工程项目 9.4.2 关键代码分析 第10章 传真高级编程 10.1 传真编程的基础知识 10.1.1 T.30传真通信协议 10.1.2 HDLC信息包 10.1.3 传真字段 10.1.4 成串信息包 10.1.5 同步线路控制 10.1.6 传真的五个阶段介绍 10.2 传真Modem的分类 10.2.1 传真分类 10.2.2 一类传真Modem 10.2.3 二类传真Modem 10.3 传真会话实例描述 10.3.1 一类传真的发送实例 10.3.2 一类传真的接收实例 10.3.3 二类传真的发送实例 10.3.4 二类传真的接收实例 10.4 DIS/DCS位映像 10.4.1 向后兼容性和可扩展性 10.4.2 新的 FCF 10.4.3 最小性能集合 10.4.4 DIS/DCS信息包的逐位解释 10.5 T.4传真图像协议 10.5.1 分辨率 10.5.2 文件尺寸 10.6 传真编码 10.6.1 一维编码(改进型哈夫曼编码) 10.6.2 二维编码(READ编码) 10.6.3 编码方式综述 10.6.4 行终码 10.6.5 页编码 10.7 传真高级编程 10.7.1 创建工程项目 10.7.2 关键代码分析

4,358

社区成员

发帖
与我相关
我的任务
社区描述
通信技术相关讨论
社区管理员
  • 网络通信
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧