socket获取回传信息_从TcpSocket上读取数据的三种⽅式由于通信路径只是单机并没有经过⽹络,因此两个进程之间的互通相对与⽹络传输是⽐较快速的。因此,进程间的交互使⽤了如下⽅式:
(见上传图⽚)
让我们看⼀下代码实现:
Java代码
public synchronized void
send(byte[] bytes)
throws IOException
{
if
(bytes != null
&& bytes.length
> 0)
{
this.bos.write(bytes);
this.bos.flush();
}
}
public synchronized byte[] receiveOnce()
throws IOException
{
byte[]
reciveBytes = new byte[0];
int
len = ad(this.b_buf,
0, this.bufferSize);
return
ArrayUtils.addAll(reciveBytes,
ArrayUtils.subarray(this.b_buf,
0,
len));
}
public byte[]
sendAndReceiveOnce(byte[]
bytes) throws IOException
{
this.send(bytes);
return
}
public synchronized void send(byte[] bytes) throws IOException
{
if (bytes != null && bytes.length > 0)
{
this.bos.write(bytes);
this.bos.flush();
}
}
public synchronized byte[] receiveOnce() throws IOException
{
byte[] reciveBytes = new byte[0];
int len = ad(this.b_buf, 0, this.bufferSize);
return ArrayUtils.addAll(reciveBytes, ArrayUtils.subarray(this.b_buf, 0, len));
}
public byte[] sendAndReceiveOnce(byte[] bytes) throws IOException
{
this.send(bytes);
iveOnce();
}
我们通过调⽤sendAndReceiveOnce()来接收并返回数据。
这样实现会导致什么问题呢?
1. 最明显的就是发送数据,和接收数据在同⼀个线程⾥边,如果运⾏在主线程,那么主线程将会在执⾏receiveOnce()的时候停滞,除⾮接收到数据或者触发超时异常。但之前已经说明了,应⽤本函数的环境是单机的进程间的通信,因此接收到数据的时间实际上就取决于Server 处理并给予响应时间的长短,不存在⽹络传输的滞留时间。所以,如果在Server响应快速的情况下,客户端Socket⼏乎感觉不到延迟太多。
2. 再⼀个明显问题就是,receiveOnce()根据其函数名称就可以得知,它只能读取⼀次,如果返回信息的长度,⼤于其缓冲区的长度,那它只能得到部分数据了。
综合分析以上两种情况,我们先解决问题2吧,看看如何读取完整的响应信息?
下⾯是我的实现⽅法:
Java代码
public synchronized byte[] blockReceive()
throws IOException
{
byte[]
reciveBytes = new byte[0];
//
偏移量
int
offset = 0;
/
/
每次读取的字节数
int
len = 0;
while(len
!= -1)
{
try
{
len = ad(this.buffer,
0, this.bufferSize);
}
catch(SocketTimeoutException
e)
{
break;
}
if(len
!= -1)
{
reciveBytes = ArrayUtils.addAll(reciveBytes, ArrayUtils .subarray(this.buffer,
0,
len));
offset = offset + len;
}
}
return
reciveBytes;
}
public synchronized byte[] blockReceive() throws IOException
{
byte[] reciveBytes = new byte[0];
// 偏移量
int offset = 0;
// 每次读取的字节数
int len = 0;
while(len != -1)
{
try
{
len = ad(this.buffer, 0, this.bufferSize);
}
catch(SocketTimeoutException e)
{
break;
}
if(len != -1)
{
write的返回值reciveBytes = ArrayUtils.addAll(reciveBytes, ArrayUtils
.subarray(this.buffer, 0, len));
offset = offset + len;
}
}
return reciveBytes;
}
这个⽅法就如同它的注释所说的那样,它总是尝试去仅可能多的读取信息,但是在触发了⼀次超时之后将会返回读取到的字节。有⼈提问:那判断流是否已经读完不是看读到最后会返回-1么?
我的回答是:返回-1取决于处理的流的源头是什么,如果是⽂件流,这种想法或许是对的,因为⽂件流的⼤⼩是固定的,持续的读,总会读到⽂件的末尾(EOF),它总会返回-1的。
就像下⾯的⽂件流在读取⽂件的实现⼀样,我们这样读取⽂件流:
Java代码
protected byte[] receiveBytes()
throws IOException
{
byte[]
reciveBytes = new byte[0];
//
偏移量
int
offset = 0;
//
每次读取的字节数
int
len = 0;
while(len
!= -1)
{
this.buffer
= new byte[bufferSize];
len = ad(this.buffer,
0, this.bufferSize);
if(len
!= -1)
{
reciveBytes = ArrayUtils.addAll(reciveBytes, this.buffer);
offset = offset + len;
}
}
return
ArrayUtils.subarray(reciveBytes, 0, offset);
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论