关于Java socket读取阻塞解决方法20150731-刘海伦

http://bbs.csdn.net/topics/350227310

2010-12-17 00:43:12
首先,你要仔细看明白read()方法的介绍:
从输入流读取下一个数据字节。返回 0 到 255 范围内的 int 字节值。如果因已到达流末尾而没有可用的字节,则返回值 -1。在输入数据可用、检测到流的末尾或者抛出异常前,此方法一直阻塞。
你的流根本就没有到达结尾,read()方法一直阻塞,怎么会返回-1呢?
socket和文件不一样,你从文件中读,读到末尾就到达流的结尾了,所以会返回-1,循环结束
socket如果不关闭的话,你的input会一直等待它发送数据,一直在等,就是所谓的阻塞了。 所以整个程序都阻塞了。
另外caofaping说的“read(byte[] b) 读取最大byte[]的大小的数据,
这里没有阻塞的原因是你只读取byte数组的数据,没有while(true)...”也说明白了为什么你用注释里面的代码不会阻塞的原因。
客户端的代码为什么不会阻塞?因为如果你在服务器端激活注释里面的代码之后,服务器发送一个消息之后就执行finally里面的代码关闭socket了,在客户端就是输入流已经到达结尾了,所以不会阻塞。如果你不用注释里面的代码,服务器端一直在阻塞的,客户端肯定也在阻塞等待。
说了这么多,不知道你明白没有
方法一:(有小bug:数据大小刚好等于这个奇数
private static final int max= 32769;
public void read(InputStream in, int max, boolean isFileStream) throws IOException {
int len = 0;
byte[] temp = new byte[max];
int minLength = isFileStream ? 0 : max;
while(true){
len = in.read(temp);
if(len > 0){
this.append(temp, len);
}

if(len < minLength){
break;
}
}
}
//如果数据大小是偶数,就能被整除,就有bug,32768。破解默认字节数组大小设置为奇数,就不会被整除。(bug:数据大小刚好等于这个奇数)
//文件流返回-1,非文件流阻塞
bc.read(in,false);
方法二:添加结束标志
在服务器端结束的时候给客户端发个消息说明已经结束了..客户端读到这个结束标志的时候也就不要再往文件里面写东西了..也结束..这样你的程序就正确了..
方法三:协议:数据长度+数据




好的,你的问题是关于Java socket和PLC通信的。在Java中,可以使用Socket API来实现网络编程,包括与PLC通信。下面是一个简单的Java代码示例,用于向PLC发送数据: ```java import java.io.*; import java.net.*; public class PLCClient { public static void main(String[] args) throws IOException { String hostName = "localhost"; // PLC的IP地址 int portNumber = 12345; // PLC监听的端口号 try (Socket socket = new Socket(hostName, portNumber); PrintWriter out = new PrintWriter(socket.getOutputStream(), true); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in))) { String userInput; while ((userInput = stdIn.readLine()) != null) { out.println(userInput); // 向PLC发送数据 System.out.println("PLC返回的数据:" + in.readLine()); // 读取PLC返回的数据 } } catch (UnknownHostException e) { System.err.println("无法连接到主机:" + hostName); System.exit(1); } catch (IOException e) { System.err.println("无法在端口 " + portNumber + " 上进行连接。"); System.exit(1); } } } ``` 在这个例子中,我们使用了Socket类来建立与PLC的连接,并使用PrintWriter和BufferedReader类来读写数据。当我们向PLC发送数据时,我们可以使用out.println()方法,当我们接收到PLC返回的数据时,我们可以使用in.readLine()方法。 请注意,这只是一个简单的例子,实际上,与PLC通信可能需要使用特定的协议和数据格式。同时需要考虑到网络延迟和数据丢失等问题。因此,如果需要进行生产环境的PLC通信,请务必仔细研究PLC的通信协议和数据格式,以确保数据的正确传输和处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值