在评估 3rd 方软件(使用 NIO 的 Java 框架)时,我们发现该框架在 Windows 上的吞吐量约为 Linux 上的 50%。
假设有一些影响 Windows 的 JVM 或操作系统设置,我们将开始测试跨两个平台的简单计算(Fibonacci、heapsort、strcat 等)和对象构建。在所有情况下,操作系统都差不多。然而,当我们使用简单的 ServerSocket 和 Client Socket (java.net jdk 1.7u5) 执行吞吐量测试时,我们注意到 Linux 吞吐量可以高达 Windows 的 10 倍,尤其是对于小消息(100 字节)。
我们的直接假设是操作系统套接字发送/接收缓冲区大小不同,并且它们在吞吐量中发挥着重要作用。或者这与在一个操作系统上启用 TcpNoDelay 而不是另一个有关。
操作系统套接字选项默认值为 ...
Linux: rcvBuf: 43690, sndBuf:86700, TcpNoDelay: No (Nagle On)
Windows7: rcvBuf: 8192, sndBuf:8192, TcpNoDelay: No (Nagle On)

public class SimpleMultiClientServer implements Runnable {
private static ExecutorService threadPool = null;
public static void main(String[] args) throws IOException {
//ExecutorService threadPool;
AppConfiguration configurations = null;
if ((configurations = AppConfiguration.readAppConfiguration(args)) == null )
System.exit(1);
//create thread pool and execute
threadPool = Executors.newCachedThreadPool();
threadPool.execute( new SimpleMultiClientServer(configurations) );
System.out.println("Hit any key to exit ....");
System.in.read();
//stop listening
threadPool.shutdown();
}
//------------------------------------------------------------------------------
private ServerSocket theServerSocket;
private boolean listening = true;
private AppConfiguration theConfigurations;
private SimpleMultiClientServer(AppConfiguration configurations) {
this.theConfigurations = configurations;
}
@Override
public void run() {
try {
theServerSocket = new ServerSocket(theConfigurations.port);
System.out.println(String.format("ServerSocket listening on port [%d]", theConfigurations.port));
if ( theConfigurations.printSocketDetails )
printSocketDetials();
setServerSocketConditioning();
} catch (IOException e) {
System.err.println(String.format("Could not listen on port: %d.", theConfigurations.port));
System.exit(-1);
}
//TODO interrupt the listending thread in order to shutdown
while (listening) {
try {
threadPool.execute( new SimpleMultiClientServerThread( theServerSocket.accept() ) );
System.out.println("Accept new client on socket ....");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
theServerSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private static class SimpleMultiClientServerThread implements Runnable {
private Socket theSocket = null;
@SuppressWarnings("unused")
private long messageCount = 0;
public SimpleMultiClientServerThread(Socket socket) {
this.theSocket = socket;
}
public void run() {
PrintWriter out = null;
BufferedReader in = null;
try {
out = new PrintWriter(theSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader( theSocket.getInputStream() ));
@SuppressWarnings("unused")
String inputLine;
while ((inputLine = in.readLine()) != null) {
messageCount++;
//TODO client should send shutdown message or end of stream marker on closing
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if ( null != out )
out.close();
if ( null != in )
in.close();
if ( null != theSocket )
theSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
private void printSocketDetials() {
//write to file
FileOutputStream fos = null;
PrintWriter pw = null;
try {
fos = new FileOutputStream("socketserver-details.log", true);
pw = new PrintWriter(fos);
pw.println("Socket (Server) details ....");
try {
if ( null != this.theServerSocket ) {
pw.println(String.format("isBound [%b]", this.theServerSocket.isBound()));
//SO_RCVBUF
pw.println(String.format("getReceiveBufferSize [%d]", this.theServerSocket.getReceiveBufferSize()));
//SO_REUSEADDR
pw.println(String.format("getReuseAddress [%b]", this.theServerSocket.getReuseAddress()));
//SO_TIMEOUT
pw.println(String.format("getSoTimeout [%d]", this.theServerSocket.getSoTimeout()));
pw.println("----------------------------------------------------------");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if ( null != pw ) {
pw.flush();
pw.close();
if ( null != fos )
pw.close();
}
}
}
private void setServerSocketConditioning() {
try {
if ( theConfigurations.rcvBufSpecified )
theServerSocket.setReceiveBufferSize(theConfigurations.rcvBuf);
if ( ( theConfigurations.rcvBufSpecified ) &&
theConfigurations.printSocketDetails ) {
printSocketDetials();
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static class AppConfiguration {
public int port;
//socket conditioning
public boolean printSocketDetails;
public int rcvBuf;
public boolean rcvBufSpecified;
public static AppConfiguration readAppConfiguration(String[] args) {
AppConfiguration configurations = new AppConfiguration();
try {
configurations.port = Integer.parseInt(args[0]);
if ( args.length > 1 ) {
String[] socketConditioningDetails = args[1].split("\\|");
configurations.printSocketDetails = Integer.parseInt(socketConditioningDetails[0]) == 1 ? true : false;
if ( socketConditioningDetails.length > 1 ) {
configurations.rcvBuf = Integer.parseInt(socketConditioningDetails[1]);
configurations.rcvBufSpecified = true;
}
}
} catch (Exception e) {
System.out.println(String.format("Exception caught while parsin app configurations, %s", e.getMessage()));
return null;
}
return configurations;
}
}
}
public class SimpleSocketClient implements Runnable {
public static void main(String[] args) throws IOException {
AppConfiguration configurations = null;
if ((configurations = AppConfiguration.readAppConfiguration(args)) == null )
System.exit(1);
if ( configurations.iterateThruByteRange ) {
//set starting message size
configurations.msgSize = configurations.startingMsgSize;
for (int i = 0; i < configurations.numIterations; i++) {
SimpleSocketClient client = new SimpleSocketClient(configurations);
client.run();
if ( configurations.msgSizeIncrementSpecified )
configurations.msgSize += configurations.msgSizeIncrement;
else //double message size for next iteration
configurations.msgSize *= 2;
if ( configurations.reduceMsgSize )
configurations.msgCount = Math.max(1000, configurations.msgCount / 2);
try {
Thread.sleep(2500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} else {
SimpleSocketClient client = new SimpleSocketClient(configurations);
client.run();
}
}
//------------------------------------------------------------------------------
private AppConfiguration theConfigurations;
private Socket theSocket;
private boolean isRunning = true;
private OutputStream obStream = null;
private PrintWriter obWriter = null;
private long[] sendTimeRecorder = null;
private SimpleSocketClient(AppConfiguration configurations) {
this.theConfigurations = configurations;
//prepare send time recorder
//sendTimeRecorder = new long[theConfigurations.msgCount];
//Arrays.fill(sendTimeRecorder, 0);
}
@Override
public void run() {
try {
if ( !connectToServer() )
return;
if ( theConfigurations.printSocketDetails )
printSocketDetials();
setSocketConditioning();
System.out.println(String.format("[%s] About to send msg len [%d] [%d] times ",
new Date().toString(),
theConfigurations.msgSize,
theConfigurations.msgCount));
if ( !theConfigurations.iterateThruByteRange ||
( theConfigurations.iterateThruByteRange && !theConfigurations.alreadyWaited) ) {
waitToContinue();
theConfigurations.alreadyWaited = true;
}
long startTimeInMillis = System.currentTimeMillis();
sendMessages();
System.out.println(String.format("All messages sent [%d] in timeMS [%d]",
theConfigurations.msgCount,
System.currentTimeMillis() - startTimeInMillis
));
//printSendTimes();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if ( null != obWriter )
obWriter.close();
if ( null != theSocket )
theSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void sendMessages() {
//prepare fixed length message
byte[] fixedLengthMessage = new byte[theConfigurations.msgSize+1];
Arrays.fill(fixedLengthMessage, (byte)0x41);
fixedLengthMessage[fixedLengthMessage.length-1] = (byte)0x0D; //carriage return
//long startTimeInNanos = 0;
int messageCount = 0;
while ( isRunning && messageCount < theConfigurations.msgCount ) {
try {
//startTimeInNanos = System.nanoTime();
obStream.write(fixedLengthMessage);
//sendTimeRecorder[messageCount] = System.nanoTime() - startTimeInNanos;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
messageCount++;
}
}
private boolean waitToContinue() {
boolean exit = false;
System.out.println("Hit any key to continue ...");
try {
int keyValue = System.in.read();
if ( keyValue == 'q' )
exit = true;
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return exit;
}
private boolean connectToServer() {
boolean connected = false;
try {
theSocket = new Socket(theConfigurations.host, theConfigurations.port);
obStream = theSocket.getOutputStream();
obWriter = new PrintWriter(theSocket.getOutputStream(), true);
connected = true;
} catch (UnknownHostException e) {
System.err.println(String.format("Don't know about host: %s.", theConfigurations.host));
System.exit(1);
} catch (IOException e) {
System.err.println(String.format("Couldn't get I/O for the connection to: %s.", theConfigurations.host));
System.exit(1);
}
return connected;
}
private void printSocketDetials() {
//write to file
FileOutputStream fos = null;
PrintWriter pw = null;
try {
fos = new FileOutputStream("socket-details.log", true);
pw = new PrintWriter(fos);
pw.println("Socket (Client) details ....");
try {
if ( null != this.theSocket ) {
pw.println(String.format("IsConnected [%b]", this.theSocket.isConnected()));
//SO_KEEPALIVE
pw.println(String.format("getKeepAlive [%b]", this.theSocket.getKeepAlive()));
//OOBINLINE
pw.println(String.format("getOOBInline [%b]", this.theSocket.getOOBInline()));
//SO_RCVBUF
pw.println(String.format("getReceiveBufferSize [%d]", this.theSocket.getReceiveBufferSize()));
//SO_REUSEADDR
pw.println(String.format("getReuseAddress [%b]", this.theSocket.getReuseAddress()));
//SO_SNDBUF
pw.println(String.format("getSendBufferSize [%d]", this.theSocket.getSendBufferSize()));
//SO_LINGER
pw.println(String.format("getSoLinger [%d]", this.theSocket.getSoLinger()));
//SO_TIMEOUT
pw.println(String.format("getSoTimeout [%d]", this.theSocket.getSoTimeout()));
//TCP_NODELAY
pw.println(String.format("getTcpNoDelay [%b]", this.theSocket.getTcpNoDelay()));
pw.println("----------------------------------------------------------");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if ( null != pw ) {
pw.flush();
pw.close();
if ( null != fos )
pw.close();
}
}
}
private void setSocketConditioning() {
try {
if ( theConfigurations.rcvBufSpecified )
theSocket.setReceiveBufferSize(theConfigurations.rcvBuf);
if ( theConfigurations.sndBufSpecified )
theSocket.setSendBufferSize(theConfigurations.sndBuf);
if ( theConfigurations.naglingEnabledSpecified )
theSocket.setTcpNoDelay(!theConfigurations.naglingEnabled);
if ( ( theConfigurations.rcvBufSpecified ||
theConfigurations.sndBufSpecified ||
theConfigurations.naglingEnabledSpecified ) &&
theConfigurations.printSocketDetails ) {
printSocketDetials();
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void printSendTimes() {
//write to file
FileOutputStream fos = null;
PrintWriter pw = null;
try {
String fileName = String.format("sendTimes-%d-%d-%s.log",
theConfigurations.msgSize,
theConfigurations.msgCount,
theConfigurations.naglingEnabledSpecified && !theConfigurations.naglingEnabled ? "WithNoNagle" : "WithNagle");
fos = new FileOutputStream(fileName, false);
pw = new PrintWriter(fos);
pw.println(Arrays.toString(this.sendTimeRecorder));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if ( null != pw ) {
pw.flush();
pw.close();
if ( null != fos )
pw.close();
}
}
}
private static class AppConfiguration {
public String host;
public int port;
public int msgSize;
public int msgCount;
@SuppressWarnings("unused")
public int msgRatePerSecond;
//socket conditioning
public boolean printSocketDetails;
public int rcvBuf;
public boolean rcvBufSpecified;
public int sndBuf;
public boolean sndBufSpecified;
public boolean naglingEnabled;
public boolean naglingEnabledSpecified;
//testing byte ranges
public boolean iterateThruByteRange;
public int startingMsgSize;
public int numIterations;
public boolean reduceMsgSize;
public int msgSizeIncrement;
public boolean msgSizeIncrementSpecified;
public boolean alreadyWaited = false;
public static AppConfiguration readAppConfiguration(String[] args) {
AppConfiguration configurations = new AppConfiguration();
try {
configurations.host = args[0];
configurations.port = Integer.parseInt(args[1]);
configurations.msgSize = Integer.parseInt(args[2]);
String[] msgCountDetails = args[3].split(":");
configurations.msgCount = Integer.parseInt(msgCountDetails[0]);
if ( msgCountDetails.length == 2 )
configurations.msgRatePerSecond = Integer.parseInt(msgCountDetails[1]);
if ( args.length > 4 ) {
String[] socketConditioningDetails = args[4].split("\\|");
configurations.printSocketDetails = Integer.parseInt(socketConditioningDetails[0]) == 1 ? true : false;
if ( socketConditioningDetails.length > 1 ) {
configurations.rcvBuf = Integer.parseInt(socketConditioningDetails[1]);
configurations.rcvBufSpecified = true;
}
if ( socketConditioningDetails.length > 2 ) {
configurations.sndBuf = Integer.parseInt(socketConditioningDetails[2]);
configurations.sndBufSpecified = true;
}
if ( socketConditioningDetails.length > 3 ) {
configurations.naglingEnabled = Integer.parseInt(socketConditioningDetails[3]) == 1 ? true : false;
configurations.naglingEnabledSpecified = true;
}
}
if ( args.length > 5 ) {
String[] byteRangeSettings = args[5].split("\\|");
configurations.iterateThruByteRange = Integer.parseInt(byteRangeSettings[0]) == 1 ? true : false;
if ( byteRangeSettings.length > 1 )
configurations.startingMsgSize = Integer.parseInt(byteRangeSettings[1]);
if ( byteRangeSettings.length > 2 )
configurations.numIterations = Integer.parseInt(byteRangeSettings[2]);
if ( byteRangeSettings.length > 3 )
configurations.reduceMsgSize = Integer.parseInt(byteRangeSettings[3]) == 1 ? true : false;
if ( byteRangeSettings.length > 4 ) {
configurations.msgSizeIncrement = Integer.parseInt(byteRangeSettings[4]);
configurations.msgSizeIncrementSpecified = true;
}
}
} catch (Exception e) {
System.out.println(String.format("Exception caught while parsin app configurations, %s", e.getMessage()));
return null;
}
return configurations;
}
}
}
java –cp . SimpleMultiClientServer 9090 [“printSocketConditioning|rbuffer size”]
printSocketConditioning : 1/0,打印到 'socketserver-details.log'rbuffer size : 以字节为单位的接收缓冲区java –cp . SimpleMultiClientServer 9090java –cp . SimpleSocketClient localhost 9090 msgSize numMessages
msgSize : 消息大小(以字节为单位)numMessages : 要发送的消息数java –cp . SimpleSocketClient localhost 9090 100 1000000java –cp . SimpleSocketClient localhost 9090 <msgSize> <numMessages> “printSocketConditioning|rbuffer|sbuffer|nagle on”]
printSocketConditioning: 1/0rbuffer : 接收缓冲区大小(以字节为单位)sbuffer : 以字节为单位发送缓冲区大小nagle on: 1/0 (相当于 TcpNoDelay 关/开)java –cp . SimpleSocketClient localhost 9090 100 1000000 “1|8192|8192|1”java –cp . SimpleSocketClient localhost 9090 msgSize numMessages [“printSocketConditioning|rbuffer|sbuffer|nagle on”
[“iterateByteRange|startSize|numIterations|reduceMsgCount|incMsgSizeBy”]
]
iterateByteRange: 1/0 ,从消息大小开始执行一系列测试 startSize并通过加倍(默认)或 incMsgSizeBy 递增, 重复 numIterationsstartSize : 以字节为单位的消息起始大小(例如 100)numIterations :例如1000000reduceMsgCount: 1/0 , 每次迭代减半或保持不变incMsgSizeBy :在每次迭代时按字节增加消息大小(例如 100)java –cp . SimpleSocketClient localhost 9090 100 1000000 “1|8192|8192|1” "1|100|20|0|100"*最佳答案
Microsoft 在 Windows(客户端)操作系统中专门针对 TCP 连接实现了限制,以防止将其用作服务器 (reference)。在 Windows Server 2008 R2 上再次运行您的测试,看看是否有任何不同。
关于java - 谁能解释 Windows (7 Pro N) 和 Linux ( Ubuntu 12-04) 之间的套接字吞吐量差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11565777/
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法
我试过重新启动apache,缓存的页面仍然出现,所以一定有一个文件夹在某个地方。我没有“公共(public)/缓存”,那么我还应该查看哪些其他地方?是否有一个URL标志也可以触发此效果? 最佳答案 您需要触摸一个文件才能清除phusion,例如:touch/webapps/mycook/tmp/restart.txt参见docs 关于ruby-如何在Ubuntu中清除RubyPhusionPassenger的缓存?,我们在StackOverflow上找到一个类似的问题:
这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub
之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m
网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识
深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal
在VMware16.2.4安装Ubuntu一、安装VMware1.打开VMwareWorkstationPro官网,点击即可进入。2.进入后向下滑动找到Workstation16ProforWindows,点击立即下载。3.下载完成,文件大小615MB,如下图:4.鼠标右击,以管理员身份运行。5.点击下一步6.勾选条款,点击下一步7.先勾选,再点击下一步8.去掉勾选,点击下一步9.点击下一步10.点击安装11.点击许可证12.在百度上搜索VM16许可证,复制填入,然后点击输入即可,亲测有效。13.点击完成14.重启系统,点击是15.双击VMwareWorkstationPro图标,进入虚拟机主
需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc
s=Socket.new(Socket::AF_INET,Socket::SOCK_STREAM,0)s.connect(Socket.pack_sockaddr_in('port','hostname'))ssl=OpenSSL::SSL::SSLSocket.new(s,sslcert)ssl.connect从这里开始,如果ssl连接和底层套接字仍然是ESTABLISHED,或者它是否在默认值7200之后进入CLOSE_WAIT,我想检查一个线程几秒钟甚至更糟的是在实际上不需要.write()或.read()的情况下关闭。是用select()、IO.select()还是其他方法完成