Configuré un servidor con ServerSocket, me conecté a él con una máquina cliente. Están conectados en red directamente a través de un interruptor y el tiempo de ping es < 1ms.Java Socket TCP: la transferencia de datos es lenta
Ahora, intento enviar una gran cantidad de datos del cliente al servidor a través del flujo de salida del socket. Tarda 23 minutos para transferir 0.6Gb. Puedo enviar un archivo mucho más grande en segundos a través de scp.
¿Alguna idea de lo que podría estar haciendo mal? Básicamente estoy bucleando y llamando a writeInt en el socket. El problema de velocidad no importa de dónde provienen los datos, incluso si solo estoy enviando un entero constante y no leyendo desde el disco.
Intenté configurar el búfer de envío y recepción en ambos lados a 4Mb, sin dados. Utilizo una secuencia amortiguada para el lector y el escritor, sin dados.
¿Echo de menos algo?
EDIT: código
Aquí es donde hago la toma
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()));
Aquí es donde hago la conexión del lado del servidor:
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();
}
}
Muy bien, aquí es donde estoy de buques de más ~ 0.6 Gb de datos.
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);
}
}
Parece bastante sencillo hasta ahora ...
Por favor, publique el código para el cliente y el servidor. –
Sí, definitivamente te estás perdiendo algo. No estoy seguro de qué. Debería publicar fragmentos del código del servidor y del cliente. –
¿Cuál es el valor de RECEIVE_BUFFER_SIZE y SEND_BUFFER_SIZE? Tengo una fuerte sospecha de que realmente envíe un paquete por cada 4 bytes ... –