如何设计一个在单个套接字上运行的读写循环(支持并行读写操作)?我必须使用多个线程吗?我的(java)解决方案有什么用吗?睡眠命令怎么样?你如何在这样的循环中使用它?
我正在尝试使用2个主题:
读
public void run() {
InputStream clientInput;
ByteArrayOutputStream byteBuffer;
BufferedInputStream bufferedInputStream;
byte[] data;
String dataString;
int lastByte;
try {
clientInput = clientSocket.getInputStream();
byteBuffer = new ByteArrayOutputStream();
bufferedInputStream = new BufferedInputStream(clientInput);
while(isRunning) {
while ((lastByte = bufferedInputStream.read()) > 0) {
byteBuffer.write(lastByte);
}
data = byteBuffer.toByteArray();
dataString = new String(data);
byteBuffer.reset();
}
} catch (IOException e) {
e.printStackTrace();
}
}
写
public void run() {
OutputStream clientOutput;
byte[] data;
String dataString;
try {
clientOutput = clientSocket.getOutputStream();
while(isOpen) {
if(!commandQueue.isEmpty()) {
dataString = commandQueue.poll();
data = dataString.getBytes();
clientOutput.write(data);
}
Thread.sleep(1000);
}
clientOutput.close();
}
catch (IOException e) {
e.printStackTrace();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
读取无法提供正确的结果,因为没有发送-1。 我该如何解决这个问题?
这个睡眠/写入循环是一个很好的解决方案吗?
答案 0 :(得分:4)
基本上有三种方法可以进行网络I / O:
阻止。在这种模式下,读取和写入将被阻塞,直到它们可以实现,因此如果您想同时执行这两个操作,则需要为每个执行两个线程。
无阻塞。在这种模式下,读取和写入将返回零(Java)或在某些语言(C)中无法满足时返回状态指示(return == -1,errno = EAGAIN / EWOULDBLOCK),因此您不需要单独的线程,但是你确实需要第三个API来告诉你什么时候可以实现 的操作。这是select()
API。
异步I / O,您可以在其中安排传输并返回某种句柄,通过该句柄可以查询传输状态,或者在更高级的API中,回调。
您当然永远不会使用您在此处使用的while (in.available() > 0)
/ sleep()
样式。 InputStream.available()
几乎没有正确的用法,这不是其中之一,睡眠实际上是浪费时间。数据可以在睡眠时间内到达,正常read()
会立即唤醒。
答案 1 :(得分:0)
您应该使用布尔变量而不是while(true)来在需要时正确关闭线程。同样是的,您应该创建多个线程,每个客户端连接一个线程,因为线程将阻塞自己,直到收到新数据(例如,使用DataInputStream()。read())。不,这不是一个真正的设计问题,每个库/框架或语言都有自己的方式从套接字监听,例如从Qt中的套接字监听你应该使用所谓的“信号和插槽”,而不是无限循环。