【发布时间】:2010-11-13 06:34:37
【问题描述】:
我用 ServerSocket 建立了一个服务器,用客户端机器连接到它。它们通过交换机直接联网,ping时间
现在,我尝试通过套接字的输出流将“大量”数据从客户端推送到服务器。传输 0.6Gb 需要 23 分钟。我可以通过 scp 在几秒钟内推送一个更大的文件。
知道我可能做错了什么吗?我基本上只是在套接字上循环和调用 writeInt。速度问题与数据的来源无关,即使我只是发送一个常量整数而不是从磁盘读取。
我尝试将两边的发送和接收缓冲区设置为 4Mb,没有骰子。我为读取器和写入器使用缓冲流,没有骰子。
我错过了什么吗?
编辑:代码
这是我制作插座的地方
System.out.println("Connecting to " + hostname);
serverAddr = InetAddress.getByName(hostname);
// connect and wait for port assignment
Socket initialSock = new Socket();
initialSock.connect(new InetSocketAddress(serverAddr, LDAMaster.LDA_MASTER_PORT));
int newPort = LDAHelper.readConnectionForwardPacket(new DataInputStream(initialSock.getInputStream()));
initialSock.close();
initialSock = null;
System.out.println("Forwarded to " + newPort);
// got my new port, connect to it
sock = new Socket();
sock.setReceiveBufferSize(RECEIVE_BUFFER_SIZE);
sock.setSendBufferSize(SEND_BUFFER_SIZE);
sock.connect(new InetSocketAddress(serverAddr, newPort));
System.out.println("Connected to " + hostname + ":" + newPort + " with buffers snd=" + sock.getSendBufferSize() + " rcv=" + sock.getReceiveBufferSize());
// get the MD5s
try {
byte[] dataMd5 = LDAHelper.md5File(dataFile),
indexMd5 = LDAHelper.md5File(indexFile);
long freeSpace = 90210; // ** TODO: actually set this **
output = new DataOutputStream(new BufferedOutputStream(sock.getOutputStream()));
input = new DataInputStream(new BufferedInputStream(sock.getInputStream()));
这是我进行服务器端连接的地方:
ServerSocket servSock = new ServerSocket();
servSock.setSoTimeout(SO_TIMEOUT);
servSock.setReuseAddress(true);
servSock.bind(new InetSocketAddress(LDA_MASTER_PORT));
int currPort = LDA_START_PORT;
while (true) {
try {
Socket conn = servSock.accept();
System.out.println("Got a connection. Sending them to port " + currPort);
clients.add(new MasterClientCommunicator(this, currPort));
clients.get(clients.size()-1).start();
Thread.sleep(500);
LDAHelper.sendConnectionForwardPacket(new DataOutputStream(conn.getOutputStream()), currPort);
currPort++;
} catch (SocketTimeoutException e) {
System.out.println("Done listening. Dispatching instructions.");
break;
}
catch (IOException e) {
e.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}
}
好的,这是我发送超过 ~0.6Gb 数据的地方。
public static void sendTermDeltaPacket(DataOutputStream out, TIntIntHashMap[] termDelta) throws IOException {
long bytesTransferred = 0, numZeros = 0;
long start = System.currentTimeMillis();
out.write(PACKET_TERM_DELTA); // header
out.flush();
for (int z=0; z < termDelta.length; z++) {
out.writeInt(termDelta[z].size()); // # of elements for each term
bytesTransferred += 4;
}
for (int z=0; z < termDelta.length; z++) {
for (int i=0; i < termDelta[z].size(); i++) {
out.writeInt(1);
out.writeInt(1);
}
}
到目前为止,这似乎很简单......
【问题讨论】:
-
请发布客户端和服务器的代码。
-
是的,你肯定错过了一些东西。不确定是什么。您应该发布服务器和客户端代码的 sn-ps。
-
RECEIVE_BUFFER_SIZE和SEND_BUFFER_SIZE的值是多少?我强烈怀疑您实际上每 4 个字节发送一个数据包......
-
在到达消息的逻辑结尾之前不要刷新任何内容。如果您在没有阅读响应的情况下进行流式传输,则根本不要刷新。并失去睡眠。这是没有意义的。
标签: java networking tcp sockets performance