您的位置:首页 > 理论基础 > 计算机网络

如何使用socket进行java网络编程(五)

2017-12-16 20:58 821 查看
本篇记录:

1、再谈readLine()方法

  2、什么是真正的长连接

最近又参与了一个socket的项目,又遇到了老生常谈的readLine()问题:对方通过其vb程序向我方socketServer程序发送报文,后天日志查看有read超时的异常。

关于line=readLine()方法,其为一个阻塞方法,遇到\r 、\n、\r\n时会返回此时为止读到的数据,作为“一行”赋值给line变量。而之后除非超时或者发送端关闭输出流,readLine()才会返回null,代表读取结束。也就是说如果不是超时或关闭流,那么readLine()读取完所有行之后仍然会一直阻塞。

下面代码为客户端的发送代码,红字为关键,正是其确保服务器端的readLine()方法结束阻塞。

Socket clientSocket = new Socket(address, port);
LOGGER.debug("网络" + address + ":" + port + "初始化已经完成,服务端已连接!");
PrintWriter writer = new PrintWriter(clientSocket.getOutputStream());
try {
// 向clientSocket中写入报文
Integer length = msg.toString().length();
String lengthStr = length.toString();
while (lengthStr.length() < 5) {
lengthStr = "0" + lengthStr;
}
System.out.println(lengthStr + msg);
writer.println(lengthStr + msg);
writer.flush();
clientSocket.shutdownOutput();
LOGGER.debug("上送信息:" + lengthStr + msg);
//等待回复
InputStream is = clientSocket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String str = br.readLine();
LOGGER.debug("读取返回信息:" + str);
System.out.println(str);
if (StringUtils.isNotEmpty(str) && str.startsWith("1|")) {
isSucc = true;
}
clientSocket.shutdownInput();
} catch (Exception ex) {
LOGGER.error("上送报文异常", ex);
System.out.println(ex.getMessage());
isSucc = false;
return isSucc;
} finally {
writer.close();

}


在C、VC、VB中也是一样的,因为网络通信底层是相通的:



最后,上述技术方案中实际上是使用TCP socket实现的一种短连接通信:客户端打开socket连接,然后发送报文,关闭输出流,接受服务端返回报文,关闭输入流,关闭连接; 服务端收到客户端socket连接,使用输入流接收上送的报文,处理,使用输出流向客户端发送返回报文。

那么真正的长连接是怎样的呢? 首先,长连接在于不是上述这种打开-发送-接收-返回-关闭的方式,而是在一段长时间内保持连接而不关闭,或者在连接空闲时超时关闭的时候,通过心跳检测机制,发现超时关闭而重新建立连接。与短连接相比,减少了打开-关闭连接的开销。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: