byte[] message = ...
Socket socket = ...
DataOutputStream dOut = new DataOutputStream(socket.getOutputStream());
dOut.write(message); //#1
... //other code 让我们假设机器1 (使用上面的代码)试图向机器2发送一些东西,而机器2试图从机器1读取字节。
根据TCP,如果机器2还没有成功读取从上面发送的数据,我可以说第1行之后的代码将不会执行吗?
但是在什么时候,我可以说机器2已经读取了数据,第1行之后的代码将执行?它发生在操作系统级别还是应用程序级别?例如,机器2操作系统将在机器1执行writeByte命令/语句后立即缓冲来自机器1的消息,那么机器2将向机器1发出信号以继续第1行吗?
或者,如果Java应用程序在应用程序级执行readByte命令/语句,机器2只会向机器1发出信号,让其继续运行?
如果整个接收过程发生在操作系统级别,我们如何控制用于缓存传入数据的缓冲区大小(在机器2中)?
发布于 2013-07-11 11:01:21
TCP通常有本地缓冲区。Java不处理由操作系统处理的通信。Java访问本地缓冲区,读取将把缓冲区中的字节清空,而写入将把字节放入缓冲区。
如果您尝试从空缓冲区读取或写入已满缓冲区,则阻塞IO的行为方式是阻塞。
在接收到数据块时,客户端将向发送者发送ack。发送器将在接收到ack时从其缓冲器中清空该数据。
请记住,沿着该路由的各种路由器和交换机可以具有它们自己的缓冲器,并且发送器可以在客户端接收任何数据之前接收ack。
可以使用setReceiveBufferSize和setSendBufferSize方法设置缓冲区大小。
http://docs.oracle.com/javase/7/docs/api/java/net/Socket.html
发布于 2013-07-11 12:13:54
如果您希望发送者等待接收者,接收者必须将某些内容发回发送者。通常这不是您应该担心的事情,因为TCP处理一端和另一端之间的所有握手。
但是在什么时候,我可以说机器2已经读取了数据,第1行之后的代码将执行?
当机器#2发送机器说它已读取来自#1的消息时
它发生在操作系统级别还是应用程序级别?
在应用程序级别,因为大多数应用程序不需要这种保证。
例如,机器2操作系统将在机器1执行writeByte命令/语句后立即缓冲来自机器1的消息,那么机器2是否会向机器1发出信号以继续第1行?
机器#1等待,直到将副本放入它的缓冲区。它不会等待将其放入#2机器缓冲区或等待其被读取。
如果
应用程序在应用程序级执行readByte命令/语句,或机器2只会向机器1发出信号,让它继续运行吗?
这样的信号不存在,除非你添加它。
如果整个接收过程发生在操作系统级别,我们如何控制用于缓存传入数据的缓冲区大小(在机器2中)?
您可以通过将其设置为您想要的大小来控制它。大多数时候你不需要改变它,你也不需要比这个更多的控件。
您必须清楚地了解您正在尝试解决的是什么真实的程序,而不是想象中的程序,并且您可能会发现TCP已经处理了您需要的东西。
发布于 2013-07-11 13:19:02
根据TCP,如果机器2还没有成功读取上面发送的数据,我可以说第1行之后的代码将不会执行吗?
不是的。除非您和对等体之间的所有中间缓冲区都已满,否则代码将继续执行。
但是在什么时候,我可以说机器2已经读取了数据,第1行之后的代码将执行?
你不能,用这段代码。如果你需要知道对等体已经读取了数据,它将不得不向你发送一条消息来说明这一点。
它发生在操作系统级别还是应用程序级别?
‘它’是什么?
例如,机器2操作系统将在机器1执行writeByte命令/语句后立即缓冲来自机器1的消息,那么机器2是否会向机器1发出信号以继续第1行?
不是的。writeByte()会将该字节放入本地内核的TCP send buffer中,您的应用程序将继续运行,除非发送缓冲区已满。同时,当您的应用程序继续运行时,TCP会将其发送缓冲区的内容发送给对等体。
如果
应用程序在应用程序级执行readByte命令/语句,或机器2只会向机器1发出信号,让它继续运行吗?
不是的。机器2根本不会“向机器1发出继续进行的信号”。
如果整个接收过程发生在操作系统级别,我们如何控制用于缓存传入数据的缓冲区大小(在机器2中)?
Socket.setReceiveBufferSize()。
https://stackoverflow.com/questions/17584032
复制相似问题