我有一个家庭作业,通过重定向标准I / O来创建一个带有客户端/服务器TCP套接字对的简单数据传输机制。我实际上有它工作,但当我尝试传输大文件(比如~5g)时,速度会急剧减慢。我正在使用BufferedInputStream和BufferedOutputStream,我想也许我可以在那里进行一些优化。我服务器的代码是:
private static final int BUF_SIZE = 2047;
public static void main(String[] args) throws IOException{
/*
* Attempt to parse command line arguments.
* @require args[0] is an int
*/
int port = 0;
try {
port = Integer.parseInt(args[0]);
} catch(NumberFormatException e) {
System.err.println("Port must be an integer in range 0 - 65535.");
System.exit(-1);
}
/*
* Bind server socket to specified port number and wait for request.
* @require port >= 0 && port <= 65535
*/
ServerSocket welcomeSocket = null;
welcomeSocket = new ServerSocket(port);
System.out.println("Now listening on port: " + port);
/*
* Accept connection from client socket.
*/
Socket connectionSocket = null;
connectionSocket = welcomeSocket.accept();
System.out.println("Client made connection");
BufferedInputStream input;
BufferedOutputStream output;
if(System.in.available() > 0) {
input = new BufferedInputStream(System.in, BUF_SIZE);
output = new BufferedOutputStream(
connectionSocket.getOutputStream(), BUF_SIZE);
} else {
input = new BufferedInputStream(
connectionSocket.getInputStream(), BUF_SIZE);
output = new BufferedOutputStream(System.out, BUF_SIZE);
}
int place;
while((place = input.read()) != -1)
output.write(place);
input.close();
output.close();
welcomeSocket.close();
connectionSocket.close();
}
客户端代码基本相同。我尝试使用不同的缓冲区大小,包括默认值(通过不指定缓冲区大小),但它们都以大致相同的速度运行。关于如何提高我的表现的任何指示?
感谢您的时间!
答案 0 :(得分:6)
while((place = input.read()) != -1)
您从缓冲区一次读取一个字节。调用此方法数百万次的开销相当大。
我建议在另一个版本的缓冲区中读取多个字节(并以相同的方式编写):
public int read(byte[] b,
int off,
int len)
示例:
byte[] myBuffer = new byte[BUF_SIZE];
while((place = input.read(myBuffer, 0, BUF_SIZE)) != 1)
output.write(myBuffer, 0, place);
答案 1 :(得分:3)
您正在读取并一次发送一个效率不高的字节,您应该读取数据块(空闲大小将是磁盘硬件缓冲区大小)。 当然,磁盘应该是你的瓶颈,这里需要时间来读取5G表盘。