关于Socket使用中读取响应消息的问题

一:关于Socket使用中读取响应消息的方法
使用Socket进行通信会涉及到读取服务端的响应消息。读取的方法可分为2类三种。

类1:一次性全部读取。

代码:
方法一:public String getResultStr(Socket sourceSocket)
{

String resultStr = null;

InputStream in;
try {
in = sourceSocket.getInputStream();
int readIndex = 5 * 1024 * 1024;
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(in), readIndex);
char[] charArray = new char[readIndex];
int read_rst = bufferedReader.read(charArray);
resultStr = new String(charArray, 0, read_rst);
bufferedReader.close();

} catch (IOException e) {
e.printStackTrace();
}

return resultStr;
}
类2:非一次性读取

方法二:一行行读
public String getResultStr(Socket sourceSocket)
{
String resultStr = null;

InputStream in;

try {
in = sourceSocket.getInputStream();
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(in));
StringBuffer responseBuffer = new StringBuffer();
String line = bufferedReader.readLine();
while (null != line)
{
responseBuffer.append(line);
line = bufferedReader.readLine();
}

bufferedReader.close();

resultStr = responseBuffer.toString();

} catch (IOException e) {
e.printStackTrace();
}

return resultStr;
}

方法三:一字节一字节读
public String getResultStr(Socket sourceSocket)
{
String resultStr = null;

InputStream in = null;

try {
in = sourceSocket.getInputStream();
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(in));

int read_rst = bufferedReader.read();

StringBuffer readBuffer = new StringBuffer();
while (-1 != read_rst)
{
char singleChar = (char) read_rst;

readBuffer.append(singleChar);
}

bufferedReader.close();

resultStr = readBuffer.toString();
} catch (IOException e) {
e.printStackTrace();
}

return resultStr;
}

其中方法一的优点是读取速度快,且不用被超时所扰。缺陷是,只能读取一定量的字节,虽然BufferedReader的构造方法提供了设置缓冲区大小的功能,但是不管设多大,都只能读取一定量的字节,据项目中的情况来看,是65536个。如果响应消息有几MB的话,这种方法是肯定不行的。但是如果读取的消息很小,在65536个字节以内,则可以使用。

方法二的优点是便于做读取后的算法操作,速度嘛也挺快。缺陷是不能精确读取。因为readLine的方法读不出’\n’,’\r\n’,所以读出来的内容其长度与实际长度有出入。

方法三是最优解。(以上只是三种方法的原型,具体业务还要具体实现)


三:关于解决Socket读取响应消息超时的分析及解决方法:

分析
在使用Socket的过程中会遇到读取响应消息超时的问题,这是为什么呢?就我现在的理解,一句话:在服务端还没有关闭连接前,客户端读取响应消息就会一直等待,直到超时。

解决方法:
1.Socket提供的setSoTimeout(int timeout) 方法
在获得Socket的实例后,设置下超时时间,然后当read或是readLine完最后一个字节或是字符串后,会抛一个InterruptedIOException,在catch里做你想做的事情,或break,或关掉连接。

2.如果服务端也是你设计的话(就是响应消息也是你拼接的),请看。
可以在服务端里拼接响应消息的方法里为响应消息加上一个‘\r\n‘,注意一定要加在消息末尾。然后用“二:关于Socket使用中读取响应消息的方法”里第三种方法来读取响应消息,注意,通信消息头中肯定会有“Content-Length“一项,先取出其值(Content-Length表示消息主体的字节长度),接着找出主体消息的起始位置(主体消息中的最前方一定要是个固定的内容),开始计算响应消息的实际字节长度,最后将取出的Content-Length的值与实际计算出的长度进行比较,如果相等就break掉,这样,就不会读到会引起超时消息末尾。

其方法1的优点时易于实现,缺陷是不安定因素太大。setSoTimeout里总要设个值,设多少呢?假设在网络正常情况下读一个1MB的响应消息需要1s,那么如果网络阻塞呢?如果你设一个很大的值,就会影响使用。
方法2的优点是不受网络因素的影响。缺陷是,如果服务端的中文字符编码与流中的中文字符编码不一致,会导致乱码,进而会影响计算的准确度。一旦计算的不准,就会超时。
不过,方法2仍是最优解。

 


我在写 PHPRPC 客户端时,就是用这种方法来跟服务器通讯的,实践证明是很有效的。

1 为什么网络流不建议用字节读取行 line = bufferreader.readLine()
2 起初我也为如何判断读取完成而恼火,读取文件流可以用(line = br.readLine()) != null(按字节读取用-1判断),但是在网络流里面这个怎么也读不对,后来别人告诉我在服务器发送完信息后用socket.shutdownOutput(),之后!= null可以判断了


你用它读网络流它仍然是按照它的 Buffer 大小来读入字节数的,所以读多了就会有麻烦了。
< 你每次都读取<="size的数据 " 不要按行去读取,你可以定义一个缓冲区byte[size] 这12个字节就表示你要接收的数据大小.如果读满了这12个字节的数据那么就读完了. 建议你先固定读取12个字节(包头定义)>(不用mina的时候项目中就这么做。)

1 缓存中有多于一行(\r\n)的纪录,那么readLine()读取一行,buff里还剩下一些
2 缓存中有不到一行的记录,那么readLine()
  (1)是阻塞,直到缓存中出现\r\n为止 ?
  (2)现在缓存中有多少就认为是一行?

我觉得很可能是第2个情况,因为一个网络流很可能没有换行,那么不可能直到超时才继续执行。

情况一:你只是希望你文件所有的内容都传到服务器上而已,那么一行读取是否为实际真的一行就不重要了,因为最终拼成的文件是完整的就够了。

情况二:你的客户端基于服务器段传输信息格式,比如说第一行是命令,第二行是版本号,那么你需要明确知道读多少是一行,那可能buff就有你说的问题了,总之仅仅需要传输完整的文件,无所谓读多读少问题。
< 命令用4个字节 令牌用12个字节  发送长度用4个字节  比如 包头可以用固定字节  你的发送包数据格式和回复包数据格式 以上连接你可以定义出 注明该次任务情况等等   就是断开连接 第三 你可以进行多次的交互 这个步骤是不确定 要编码的编码等等 要分包的分包 这个和你具体业务有关  发送请求 第二次 服务端返回任务令牌  请求连接 第一 大概可以分为以下几个步骤 你可以靠令牌去实现这个.>

 

保姆级教程:用掘金量化API手把手复现一个年化17%的网格交易策略(附完整Python代码) 本文提供了一份详细的掘金量化API教程,手把手教你构建一个年化17%的网格交易策略。通过完整的Python代码实现,深入解析网格交易的核心逻辑、参数配置和动态调仓机制,帮助量化新手快速掌握策略开发全流程。教程包含环境配置、代码实现、回测分析和常见问题解答,是学习量化投资的实用指南。 阅读详情

相关推荐

S型速度曲线C程序实现

S型速度曲线C语言程序实现 前言 S型曲线相较于梯形速度曲线具有运行更加平稳的特点,S型曲线共有八种运行情况,感兴趣可以查阅相关文献 代码段 #include <stdio.h> #include <math.h> #define FP64 double int main(void) { /**************************** 定义相关变量(需要映射到PLC寄存器才能进行监控) ***********************/ FP6

LSX312441548的博客 8392

C语言 使用socket发送http请求接收任意大小响应内容

最近想使用JNI完成http请求,由于之前有C语言基础,就来了兴致研究了一番。 请务必理解http的传输层数据格式,\r\n和\r\n\r\n,例: #define HTTP_POST "POST /%s HTTP/1.1\r\nHOST: %s:%d\r\nAccept: */*\r\n"\ "Content-Type:application/x-www-form-urlencod...

VcStrong的专栏 2235

美团外卖 mtgsig 1.2 逆向工程与补环境实战指南

本文深入解析了美团外卖核心风控参数mtgsig 1.2的生成机制与逆向实战。通过拆解其复杂的JSON结构,揭示了设备指纹、环境信息加密等关键字段。重点阐述了在Node.js中模拟浏览器环境(补环境)的核心方法,包括DOM/BOM对象、本地存储及Canvas/WebGL等高级指纹的模拟技巧,为安全研究和合规自动化测试提供了一套完整的技术指南。

uber9的博客 410

socket阻塞的解决办法,socket客户端收不到响应报文的处理

问题:java编写的socket服务端,C编写的客户端,通信的时候,C接收不到响应报文。 原因:服务端使用了readLine(),一直在等待客户端报文的结束符,造成阻塞。 处理办法:用缓存替换readLine(),具体代码如下: public void run() { PrintWriter pw = null; OutputStreamWriter os = null; InputS

ttheng88的博客 2万+

Qt+WebAssembly学习笔记(六)win10+Qt6.4.0rc1开发环境搭建

前言:因项目的缘故,笔者有段时间没测试了,官方也修复了很问题,笔者今天记录下最新版本环境搭建。

aggs1990的专栏 3766

TSP、MTSP问题遗传算法详细解读及python实现

写在前面 遗传算法是一种求解NPC问题的启发式算法,属于仿生进化算法族的一员。仿生进化算法是受生物行为启发而发明的智能优化算法,往往是人们发现某种生物的个体虽然行为较为简单,但生物集群通过某种原理却能表现出智能行为。于是不同的人研究不同的生物行为原理,受到启发而发明出新的仿生进化算法。比如免疫优化算法,蚁群算法,模拟退火算法等,这些算法以后也会简单介绍。 本文的主题是遗传算法,该算法也是受到生物行为启发。物竞天择,适者生存,优胜劣汰,是该优化算法的核心思想。笔者在业务中需要用到遗传算法求解TSP问题,但是网

weixin_47675950的博客 9306

socket服务器为什么没有响应,我无法通过socket.receive接收服务器完整响应

我用socket.send向服务器发送命令,服务器响应我但我无法收到完整的响应 . 缓冲区大小小吗?问题出在哪儿?!!private void send(string toSend){byte[] data = new byte[8192];int dataLenght = 0;string ServerResponse = "";try{data = Encoding.ASCII.GetByte...

weixin_42200791的博客 1116

用Python写个彩票小助手:自动生成双色球/大乐透号码并保存到桌面

本文介绍如何使用Python开发一个智能彩票助手,实现双色球和大乐透号码的随机生成与桌面文件保存功能。通过详细的代码示例,包括随机号码生成、文件操作、用户交互和错误处理,帮助Python初学者快速掌握实用工具开发技巧。

weixin_42566121的博客 519

socket客户端向服务端持续发送信息,一段时间后服务端就收不到客户端发来的信息可能是什么原因...

有多种原因可能导致服务端收不到客户端发来的信息: 网络问题:网络中断或延迟过高可能会影响到数据的传输。 缓存问题:如果客户端的缓存已满,那么服务端可能会丢失一些信息。 程序 bug:如果客户端或服务端的代码存在 bug,那么可能导致消息丢失。 资源限制:如果客户端或服务端的系统资源不足,那么可能导致消息丢失。 如果遇到这种情况,建议通过跟踪网络数据、检查代码和监测系统资源使用情况来确定...

weixin_42613017的博客 3181

Sigrity Power SI Model Extraction模式如何提取电源网络的S参数和阻抗操作指导(一)

34. 默认格式是BNP format格式,会被Sigrity识别的S参数文件,在仿真完成后,默认会在文件夹中生成bnp和ckt(MCP)文件,无需这步操作。由于port设置的ref Z是50ohm,实际上电源网络的阻抗是没有这么高的,所以S参数回损曲线是基本上全反射的一个状态。Sigrity PowerSI是频域电磁场仿真工具,以下图为例介绍如果用它观测电源的网络的S参数以及阻抗的频域曲线.42. Spice格式的加载进来图标是橙色的,BNP格式的图标是灰色的。

weixin_54787054的博客 1279

【深度学习|多实例学习】多实例学习(Multiple Instance Learning, MIL)的起源、发展和应用,附代码(一)

【深度学习|多实例学习】多实例学习(Multiple Instance Learning, MIL)的起源、发展和应用,附代码(一)

2401_89898861的博客 1923

记一次socket 接收消息产生的bug

今天项目产生了bug,解决后发现了bug产生的原因: 由于客户端会进行socket消息的处理,服务端负责消息的发送。所以如果客户端处理消息“慢”,或者服务端发送消息“快”,则会导致客户端接收消息的时候会将那些未处理的正在队列中排队的消息都接收过来连成一条消息,导致信息处理出错。 这个时候就要求我们接收的时候不仅要看消息包头,还要看消息中的消息长度信息。        下面这个消息就包括两个包

X-Prince的博客 1723

手把手教你YOLOv8/YOLOv11分割训练自己数据集和推理,并教你使用Labelme工具标注数据(附分割网络结构图)

YOLOv8-seg 和 YOLOv11-seg 都是一种高效实例分割算法,实例分割模型的输出是一组勾勒出图像中每个物体的遮罩或轮廓,以及每个物体的类标签和置信度分数。当你不仅需要知道物体在图像中的位置,还需要知道它们的具体形状时,实例分割就非常有用了,功能非常强大,可以应对各种视觉任务。 YOLOv11-seg 则在 YOLOv8-seg 基础上进一步魔改了模型架构,相对分割速度可能更快,其他指标性能有待测试。实例分割可以用于自动驾驶、医疗图像处理、智能农业监控等领域。

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 4475

javasocket连续给服务器发送消息,Java通过Socket发送和接收多条消息

我们需要实现一个Socket客户端,它应该连接到一个接受TCP连接的服务器。如果我通过netcap与服务器进行通信,我会立即得到它的响应(通过命令行)。Java通过Socket发送和接收多条消息的工作流程是:nc 99.0.99.84 20000然后我发送连接请求到服务器*99*0##我得到的ACK响应返回*#*1##我送我的要求*#18*802*86##我得到的回应回*#18*802*86*22...

weixin_42300418的博客 2419

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

java socket read 堵塞问题的解决方法

最近在学socket的网络编程,但遇到了一点问题,就是每次循环从缓冲区读数据时,如果缓冲区没有数据,这时候read方法会堵塞,此时也没有办法输入了。后来发现了主要有两种解决方法: 在消息开头标记消息长度 新启动一个线程进行读操作,阻塞就阻塞吧,反正读写没在一个线程(也算某种意义的读写分离) 这是最初会阻塞的代码 后来就用了读写分离 class read implements Runnable{ BufferedReader bufferedReader; read(Buffere

weixin_43919032的博客 2003

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

用CSocket重写OnReceive()之后,出现消息收不到的情况

winsock实验,多人聊天室,遇到消息收不到的情况 原先代码: void CCSocket::OnReceive(int nErrorCode) { // TODO: 在此添加专用代码和/或调用基类 CSocket::OnReceive(nErrorCode); //调用CTCDlg类的相应函数处理 if (nErrorCode == 0) m_pDlg->OnReceive(); } 原因是:没有让Socket改变响应事件的发式 解决方法:在OnReceiv...

wssyaoqifei的博客 2822

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

java socket 断开连接_JAVA SOCKET客户端连接上就断开。求帮忙看看。

该楼层疑似违规已被系统折叠隐藏此楼查看此楼目前服务端是用C做的。JAVA客户端订阅一个消息后,就等待服务器发送消息。客户端木有问题,现在客户端不知道哦哪错了。连上就断,连上就断。package com.Demos;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;im...

weixin_42500374的博客 1146

java socket分包粘包 代码_分享java中处理socket通信过程中粘包情况的实例代码

本篇文章主要介绍了java中处理socket通信过程中粘包的情况,具有一定的参考价值,感兴趣的小伙伴们可以参考一下这两天学习了java中处理socket通信过程中粘包的情况,而且很重要,所以,今天添加一点小笔记。处理粘包程序是客户端的接受消息线程:客户端:import java.io.InputStream;import java.io.InputStreamReader;import java....

weixin_35740875的博客 546

别人通讯项目总结

最近做了一个小型的通讯项目,有一点体会,在这里拿来和大家分享一下: 一:关于Socket的长连接 这个项目中,客户提出了“一次连接,10次交互”的需求,就是说创建一个Socket后,在客户端与服务端完成10次交互前(客户端请求,服务端响应算一次交互),不会被关掉。起初按照这种思路来做Socket的长连接,发现在使用阻塞IO的情况下,如果,在一次交互后不关闭Socket,那么下次客户端虽然可以正常发

lsz105的专栏 551

用Socket做一个通讯项目的一点心得

最近做了一个小型的通讯项目,有一点体会,在这里拿来和大家分享一下: 一:关于Socket的长连接 这个项目中,客户提出了“一次连接,10次交互”的需求,就是说创建一个Socket后,在客户端与服务端完成10次交互前(客户端请求,服务端响应算一次交互),不会被关掉。起初按照这种思路来做Socket的长连接,发现在使用阻塞IO的情况下,如果,在一次交互后不关闭Socket,那么下次客户端虽然可以正常发...

wsq198760的专栏 239

java学习之服务端和客服端

学习了java的多线程,参考了一部分别人的代码,写了一个简单的客户端和服务器端的程序,服务器要在客户端之前运行,不然在运行客户端的时候会报错,然后服务器只能运行一次,多次运行也会报错,代码如下。。。package com.jk.net; import java.io.BufferedOutputStream; import java.io.IOException; import java.net

季科的博客 614

php 做服务端,PHP编程实现的TCP服务端和客户端功能示例

本文实例讲述了PHP编程实现的TCP服务端和客户端功能。分享给大家供大家参考,具体如下:1、修改php.ini,打开extension=php_sockets.dll2、服务端程序SocketServer.php//确保在连接客户端时不会超时set_time_limit(0);//设置IP和端口号$address = "127.0.0.1";$port = 3046;/*** 创建一个SOCKET...

weixin_39735005的博客 497

java通过TCP实现HL7医疗系统传输协议

java通过TCP实现HL7医疗系统传输协议时遇到的问题

小软的博客 4724

BIO 多客户端,多线程,一个服务端

循环建立线程,每当有一个socket,就会建立一个线程与之绑定,并由此执行任务。创建客户端,创建一个socket与服务端连接,并向服务端输出字符流。创建一个独立的线程来处理这个客户端与这个客户端。定义一个死循环,负责不断的接受客户端的。BIO 多客户端,多线程,一个服务端。使用循环不断的发送消息给服务器接收。以实现输出从客户端得到的字符流。在不同客户端向服务器端输出。创建一个继承于线程的类。

2303_76839537的博客 508

c语言中void msg,如何连接到IRC服务器/解析C语言(提供代码)的IRC MSG/PING-PONG处理...

正在用C语言编写IRC客户端。并在连接到serwer时遇到了一些问题。 我碰到下面当我运行程序:如何连接到IRC服务器/解析C语言(提供代码)的IRC MSG/PING-PONG处理输出Set Fully Qualified host Domain Name(human readable): ::automaticaly provided::Set the port number of the s...

weixin_30162121的博客 241

Socket使用中读取响应消息的3种方法

类1:一次性全部读取。 代码: 方法一: [code="java"]public String getResultStr(Socket sourceSocket) { String resultStr = null; InputStream in; try { in = sourceSocket.getInputStream(); int readIndex = 5 ...

chillwind 1718
上一篇: codetemplates eclipse 注释模块
下一篇: 内存泄露和内存溢出
Li Chuan
博客等级 码龄14年 0粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值