在做j2se中用socket传输文件速度很慢,大概30k/s,如果谁能解决这个速度问题,提高到100k/s左右,将给予500块的酬劳。
[b]问题补充:[/b]
联系QQ(116870791)
500块钱一个问题
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
- 邀请回答
-
1条回答 默认 最新
- wanghaolovezlq 2009-11-30 08:46关注
用nio异步I/O来实现socket传输就快多了
[code="java"]
package nio.file;import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.Iterator;/**
- 测试文件下载的NIOServer
-
@author tenyears.cn
*/
public class NIOServer {
static int BLOCK = 4096;
static String charCoding = "utf-8";
// 处理与客户端的交互
public class HandleClient {
protected FileChannel channel;
protected ByteBuffer buffer;public HandleClient() throws IOException { this.channel = new FileInputStream(filename).getChannel(); this.buffer = ByteBuffer.allocate(BLOCK); } public ByteBuffer readBlock() { try { buffer.clear(); int count = channel.read(buffer); buffer.flip(); if (count <= 0) return null; } catch (IOException e) { e.printStackTrace(); } return buffer; } public void close() { try { channel.close(); } catch (IOException e) { e.printStackTrace(); } }
}
protected Selector selector;
protected String filename = "c:\file.war"; // a big file
protected ByteBuffer clientBuffer = ByteBuffer.allocate(BLOCK);
protected CharsetDecoder decoder;public NIOServer(int port) throws IOException {
selector = this.getSelector(port);
Charset charset = Charset.forName(charCoding);
decoder = charset.newDecoder();
}// 获取Selector
protected Selector getSelector(int port) throws IOException {
ServerSocketChannel server = ServerSocketChannel.open();
Selector sel = Selector.open();
server.socket().bind(new InetSocketAddress(port));
server.configureBlocking(false);
server.register(sel, SelectionKey.OP_ACCEPT);
return sel;
}// 监听端口
public void listen() {
try {
for (;;) {
selector.select();
Iterator iter = selector.selectedKeys()
.iterator();
while (iter.hasNext()) {
SelectionKey key = iter.next();
iter.remove();
handleKey(key);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}// 处理事件
protected void handleKey(SelectionKey key) throws IOException {
if (key.isAcceptable()) { // 接收请求
ServerSocketChannel server = (ServerSocketChannel) key.channel();
SocketChannel channel = server.accept();
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_READ);
} else if (key.isReadable()) { // 读信息
SocketChannel channel = (SocketChannel) key.channel();
int count = channel.read(clientBuffer);
if (count > 0) {
clientBuffer.flip();
CharBuffer charBuffer = decoder.decode(clientBuffer);
System.out.println("Client >>" + charBuffer.toString());
SelectionKey wKey = channel.register(selector,
SelectionKey.OP_WRITE);
wKey.attach(new HandleClient());
} else
channel.close();
clientBuffer.clear();
} else if (key.isWritable()) { // 写事件
SocketChannel channel = (SocketChannel) key.channel();
HandleClient handle = (HandleClient) key.attachment();
ByteBuffer block = handle.readBlock();
if (block != null)
channel.write(block);
else {
handle.close();
channel.close();
}
}
}public static void main(String[] args) {
int port = 12345;
try {
NIOServer server = new NIOServer(port);
System.out.println("Listernint on " + port);
while (true) {
server.listen();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
[/code]
[code="java"]
package nio.file;import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.util.Iterator;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;/**
- 文件下载客户端
-
@author tenyears.cn
*/
public class NIOClient {
static int SIZE = 100;
static InetSocketAddress ip = new InetSocketAddress("localhost", 12345);// CharsetDecorder并不是线程安全的,在高并发的状态下会出问题。
static CharsetEncoder encoder = Charset.forName("utf-8").newEncoder();static class Download implements Runnable {
protected int index;public Download(int index) { this.index = index; } public void run() { try { long start = System.currentTimeMillis(); SocketChannel client = SocketChannel.open(); client.configureBlocking(false); Selector selector = Selector.open(); client.register(selector, SelectionKey.OP_CONNECT); client.connect(ip); ByteBuffer buffer = ByteBuffer.allocate(8 * 1024); int total = 0; FOR: for (;;) { selector.select(); Iterator<SelectionKey> iter = selector.selectedKeys() .iterator(); while (iter.hasNext()) { SelectionKey key = iter.next(); iter.remove(); if (key.isConnectable()) { SocketChannel channel = (SocketChannel) key .channel(); if (channel.isConnectionPending()) channel.finishConnect(); channel.write(encoder.encode(CharBuffer .wrap("Hello from " + index))); channel.register(selector, SelectionKey.OP_READ); } else if (key.isReadable()) { SocketChannel channel = (SocketChannel) key .channel(); int count = channel.read(buffer); if (count > 0) { total += count; buffer.clear(); } else { client.close(); break FOR; } } } } double last = (System.currentTimeMillis() - start) * 1.0 / 1000; System.out.println("Thread " + index + " downloaded " + total + "bytes in " + last + "s."); } catch (IOException e) { e.printStackTrace(); } }
}
public static void main(String[] args) throws IOException {
ExecutorService exec = Executors.newFixedThreadPool(SIZE);
for (int index = 0; index < SIZE; index++) {
exec.execute(new Download(index));
}
exec.shutdown();
}
}
[/code]
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报
悬赏问题
- ¥15 outlook无法配置成功
- ¥30 这是哪个作者做的宝宝起名网站
- ¥60 版本过低apk如何修改可以兼容新的安卓系统
- ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
- ¥50 有数据,怎么建立模型求影响全要素生产率的因素
- ¥50 有数据,怎么用matlab求全要素生产率
- ¥15 TI的insta-spin例程
- ¥15 完成下列问题完成下列问题
- ¥15 C#算法问题, 不知道怎么处理这个数据的转换
- ¥15 YoloV5 第三方库的版本对照问题