Desafortunadamente, la respuesta de Jon Skeet deja una gran parte de la imagen: el tamaño del búfer de envío y el bandwidth-delay product de la tubería por la que está escribiendo.
Si está tratando de enviar datos a través de una tubería grande con un solo socket, y desea que TCP llene esa tubería, necesita usar un tamaño de búfer de envío que sea equivalente al producto de ancho de banda de la tubería. De lo contrario, TCP no llenará la tubería porque no dejará suficientes 'bytes en vuelo' en todo momento.
Considere una conexión que tiene una velocidad de 1 gigabit y tiene una latencia en un sentido de 10 milisegundos, en promedio. El tiempo de ida y vuelta (es decir, la cantidad de tiempo que transcurre entre el envío de un paquete por el socket y el tiempo que recibe el ack para ese paquete y, por lo tanto, sabe enviar más datos) suele ser el doble de la latencia.
Entonces, si tiene una conexión de 1 gigabit y un RTT de 20 milisegundos, esa tubería tiene 1 gigabit/seg * 20 milisegundos == 2.5 megabytes de datos en vuelo en todo momento si se utiliza por completo.
Si su búfer de envío TCP está a menos de 2.5 megabytes, entonces ese socket nunca utilizará completamente el conducto: nunca obtendrá un gigabit/seg de rendimiento de su socket.
Si su aplicación usa muchos sockets, entonces el tamaño agregado de todos los buffers de envío TCP debe ser de 2.5 MB para utilizar completamente esta tubería hipotética de 1 gigabit/20 ms RTT. Por ejemplo, si usa búferes de 8192 bytes, necesita 306 zócalos TCP simultáneos para llenar esa tubería.
Me gustaría aumentar el tamaño del búfer si es posible. Estábamos considerando simplemente hacer 32K, pero estaba preocupado por el escenario anterior donde el comando de recepción no obtendría todo, aunque lo envié en un solo envío. – uriDium
Lo siento, me olvidé de mencionar que estamos haciendo esto en modo bloqueo. Sin embargo, no creo que marque la diferencia. – uriDium
@uriDium: debe escribir su código para que no dependa de recibir todo desde un único envío en una recepción. Ese no es el modelo que usa TCP, es un modelo * stream *. Si desea segmentar esa secuencia en mensajes distintos, debe usar un delimitador o escribir un prefijo de longitud para cada mensaje, de modo que el cliente sepa cuánto leer. –