所以我正在试验套接字缓冲区的大小,并创建了两个测试用例
Case 1[server sends data to client]
首先,我们有一个服务器,它向客户机发送100字节的数据
public static void main(String[] args)throws Exception
{
try(ServerSocket server=new ServerSocket())
{
server.bind(new InetSocketAddress(InetAddress.getLocalHost(),2500));
byte[] data=new byte[100];
for(int i=0;i<data.length;i++){data[i]=(byte)i;}
while(true)
{
try(Socket client=server.accept())
{
try(OutputStream output=client.getOutputStream())
{
output.write(data);
}
}
}
}
}
接下来我们有一个客户端,它只读取接收到的Receive Buffer字节并打印出来,但我已经将Receive Buffer字节设置为25字节.因此,我希望服务器发送4个数据包,每个数据包大小为25字节.
public static void main(String[] args)throws Exception
{
try(Socket client=new Socket())
{
//receive window as 25 bytes
client.setReceiveBufferSize(25);
client.setSoLinger(true,0);
client.bind(new InetSocketAddress("192.168.1.2",5000));
client.connect(new InetSocketAddress(InetAddress.getLocalHost(),2500),2000);
try(InputStream input=client.getInputStream())
{
int length;
byte[] data=new byte[100];
while((length=input.read(data))>0)
{
System.out.println(Arrays.toString(Arrays.copyOfRange(data,0,length)));
System.out.println("============");
}
}
}
}
果然,在使用wire shark判断服务器端发送的数据包时,我看到了4个数据包(忽略格式错误的数据包,因为在客户端接收数据时没有错误,有时显示格式错误,有时没有错误),每个数据包的负载大小为25字节.
进一步确认每个数据包是25字节,判断从客户端发送的ACK窗口数据包
因此,在设置从客户端服务器发送的数据包的接收缓冲区大小后, case 1就完成了
Case 2[Client sends data to server]
角色颠倒了,这次我们在绑定前设置ServerSocket Receive Buffer size,如下所示
public static void main(String[] args)throws Exception
{
try(ServerSocket server=new ServerSocket())
{
//server receive window
server.setReceiveBufferSize(10);
server.bind(new InetSocketAddress(InetAddress.getLocalHost(),2500));
int length;
byte[] data=new byte[100];
while(true)
{
try(Socket client=server.accept())
{
try(InputStream input=client.getInputStream())
{
while((length=input.read(data))>0)
{
System.out.println(Arrays.toString(Arrays.copyOfRange(data,0,length)));
System.out.println("============");
}
}
}
}
}
}
客户端发送数据时,不需要额外设置,如下所示
public static void main(String[] args)throws Exception
{
try(Socket client=new Socket())
{
client.setReuseAddress(true);
client.connect(new InetSocketAddress(InetAddress.getLocalHost(),2500),2000);
byte[] data=new byte[100];
for(int i=0;i<data.length;i++){data[i]=(byte)i;}
try(OutputStream output=client.getOutputStream()){output.write(data);}
}
}
由于服务器表示只愿意接收10字节的数据包,我希望客户端发送10个数据包,每个数据包的大小为10字节.果然,在使用wire shark判断服务器端接收的数据包后,我得到了预期的输出
这就完成了对客户端和服务器端接收缓冲区的理解.如果一方广播其接收缓冲区大小,另一方在每次数据包传输时只发送总意义上的数据量.
现在更难理解的部分是发送缓冲区.我对发送缓冲区的理解是
保存套接字发送的字节,只有在
因此,如果发送方的发送缓冲区=10字节,而接收方的接收缓冲区=30字节.发送方仍然应该只发送10个字节,因为它只能保存那么多数据,然后必须由接收方确认,然后才能发送接下来的10个字节,以此类推.但尽管我在服务器端和客户端设置了发送缓冲区,如下所示
1)Client sends data to server
server side=ServerSocket.setReceiveBufferSize(30);
client side=client.setSendBufferSize(10);
2)Server sends data to client
server side=serverSocket.accept().setSendBufferSize(10);
client side=client.setReceiveBufferSize(30);
使用wire shark在接收方接收的数据包总是相同的.i、 e发送方总是发送大小为30字节的数据包.i、 e发送方总是由接收方的设置控制
a) 我的理解哪里出错了?
b) 上面介绍的一个非常简单的测试用例,其中发送缓冲区实际上在客户端和;服务器端将不胜感激