Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java';发送数据时的TCP套接字类块_Java_Sockets_Tcp_Blocking - Fatal编程技术网

Java';发送数据时的TCP套接字类块

Java';发送数据时的TCP套接字类块,java,sockets,tcp,blocking,Java,Sockets,Tcp,Blocking,当我使用Javaa的Socket类发送字节数组时,write调用是否会在下面的代码块中执行,直到它验证接收者是否收到了数据 byte data[] = ...; Socket socket = ...; socket.getOutputStream().write(data); // blocking ? 我问的原因是,如果我有一个套接字列表,我想将相同的数据发送到其中,我想尽可能高效地发送它,也就是说,有没有比这更好的方法: ArrayList<Socket> sockets

当我使用Javaa的Socket类发送字节数组时,write调用是否会在下面的代码块中执行,直到它验证接收者是否收到了数据

byte data[] = ...;
Socket socket = ...;

socket.getOutputStream().write(data); // blocking ?
我问的原因是,如果我有一个套接字列表,我想将相同的数据发送到其中,我想尽可能高效地发送它,也就是说,有没有比这更好的方法:

ArrayList<Socket> sockets = ...;
byte data[] = ...;

for(int i = 0; i < sockets.size(); i++)
  sockets.getOutputStream().write(data);
ArrayList套接字=。。。;
字节数据[]=。。。;
对于(int i=0;i
TCP握手发生在
connect(2)
时间,而不是
write(2)
时间

write(2)
的调用将被阻止,直到OS TCP发送缓冲区耗尽,足以接受来自程序的更多数据。(我无法想象操作系统会为一个空闲字节取消阻止
写入(2)
操作。)


您唯一能保证的是,客户机在过去接受过数据,并且不会落后于会话的TCP窗口大小加上内部OS缓冲区的大小。无论这些数据是否已到达另一个端点上的应用程序,这都是另一层缓冲区——远程对等机上的TCP堆栈将确认接收到的数据,并在应用程序有机会处理它之前将其存储在缓冲区中。

因此,您的意思是,一旦数据到达另一个端点上的TCP层,它将解除阻止堆栈,不必等待与客户端的整个tcp握手完成?@gamemb,在握手完成之前,您的代码不会继续执行
write()
调用。(握手在每个会话的
connect()
时间发生一次。)但是,如果本地TCP发送缓冲区释放了足够的空间来接受
write()
调用,则代码将解除阻止,这可能比远程对等方接收到的和
ACK
调用的大小提前64KB窗口+8KB缓冲区大小。(请注意,64KB的窗口只是一个猜测——使用,窗口可能会有MB大,几乎高达1GB的数据。但需要专门的环境才能传输1GB的数据。:)是的,我知道。所以,请记住,有没有更好的方法将相同的数据发送到多个客户端,而只需像上面这样一个简单的循环?@gamernb,两种可能的方法是(a)每个TCP会话使用一个线程,这样阻塞只影响一个线程/连接,而不是阻碍所有数据传输的进度(b)使用Java的工具将数据写入准备接受写入的套接字(这与C函数相对应)。如果您尝试在几乎相同的时间向客户端发送同步的游戏数据,这可能是一个更好的选择。