Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 2 Feb 2000 15:54:08 +0100 (CET)
From:      sebster@sebster.com (Sebastiaan van Erk)
To:        freebsd-questions@freebsd.org
Subject:   TCP_NODELAY
Message-ID:  <20000202145409.225685DC3@eeyore.sebster.com>

next in thread | raw e-mail | index | archive | help

--ELM949503248-12168-0_
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit

Hi there,
 
I tried the following code to disable Nagle's algorithm, but it doesn't 
seem to work: 
 
   int d = 1;
   setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (void *)&d, sizeof(d));

One reason this bugs me is because I do succeed in Java to turn off
Nagle's algorithm, and it DOES work, and furthermore, in ssh2 the code
used to turn off Nagle's algorithm is identical to the code above.
My ssh is very slow, so I thought this could be the problem (since
telnet is really fast).

My OS is FreeBSD 3.4 STABLE. If I compile the program under Linux,
Solaris, or HP-UX, it works fine.

I attached both the C program and the Java program which I use to test
the TCP_NODELAY settings.

To compile and run the C program simply do a 
  cc -o tcpdelay tcpdelay.c
  ./tcpdelay

To compile and run the Java program simply do a
  javac TCPDelayTest.java
  java TCPDelayTest true
(By using true/false as a parameter one can enable/disable Nagle's algorithm
to see the difference in speed)

Can anybody tell me what is going wrong?

Greetings,
Sebastiaan van Erk

--ELM949503248-12168-0_
Content-Type: text/plain; charset=ISO-8859-1
Content-Disposition: attachment; filename=tcpdelay.c
Content-Description: tmp/wave/comm.c
Content-Transfer-Encoding: 7bit

#include <stdio.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <netdb.h>
#include <time.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/tcp.h>
#include <netinet/in.h>

#define MESSAGE_LENGTH 20

void SendData();
void ReceiveData();

int main()
{
   unsigned short initport, sendport, receiveport;
   int initskt, sendskt, receiveskt;
   struct sockaddr_in addr;
   size_t addrlen;
   struct timeval tp1, tp2;
   struct timezone tpz;
   int i=0;
   int window_size=(int)(1.5 * MESSAGE_LENGTH);
   int nodelay=1;

   initskt = OpenTcpSocket(&initport);
   printf("Opened init socket on port %d\n", initport);
   listen(initskt, 1);
   setsockopt(initskt, IPPROTO_TCP, TCP_NODELAY, (void *)&nodelay, sizeof(nodelay));

   receiveskt = OpenTcpSocket(&receiveport);
   printf("Opened receive socket on port %d\n", receiveport);
/*   setsockopt(receiveskt, SOL_SOCKET, SO_RCVBUF, (char *)&window_size, sizeof(window_size)); */

   addrlen = sizeof(struct sockaddr_in);
   if (getsockname(initskt, (struct sockaddr *)&addr, &addrlen) != 0)
   {
      fprintf(stderr, "Unable to get send socket name.\n");
      exit(1);
   }
   if (connect(receiveskt, (struct sockaddr *)&addr, addrlen) < 0)
   {
      fprintf(stderr, "Failed to connect to target socket.");
      exit(1);
   }
   printf("Connected receivesocket & initsocket.\n");

   sendskt = accept(initskt, (struct sockaddr *)&addr, &addrlen);
   printf("Accepted connection.\n");

   for (i=0; i<100; i++)
   {
      gettimeofday(&tp1, &tpz);
      SendData(sendskt);
      ReceiveData(receiveskt);
      gettimeofday(&tp2, &tpz);
      printf("Total time needed to send & receive %d bytes: %1.5f\n", MESSAGE_LENGTH,
         ((float)((1000000*tp2.tv_sec + tp2.tv_usec) - ((1000000*tp1.tv_sec) + tp1.tv_usec)))/1000000);
   }
   return(0);
}

int OpenTcpSocket(unsigned short *portp)
{
   int skt;
   struct sockaddr_in addr;
   size_t addrlen;
   unsigned short port;
   if ((skt = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) <= 0)
   {
      fprintf(stderr, "Can't create socket.\n");
      exit(1);
   }
   bzero(&addr, sizeof(struct sockaddr_in));
   addr.sin_family = AF_INET;
   addr.sin_addr.s_addr = 0;
   port = 0;
   addr.sin_port = htons(port);
   if (bind(skt, (struct sockaddr *)&addr, sizeof(addr)) != 0)
   {
      fprintf(stderr, "Unable to bind socket to port.\n");
      exit(1);
   }
   return(skt);
}

void SendData(int skt)
{
   char buf[MESSAGE_LENGTH+1];
   int nbytes, i;

   for (i=0; i<MESSAGE_LENGTH; i++) buf[i]='a';
   buf[MESSAGE_LENGTH] = '\0';

   printf("Sending data..\n");
   nbytes = send(skt, buf, strlen(buf), 0);
   printf("Sended %d bytes\n", nbytes);
}

void ReceiveData(int skt)
{
   char buf[MESSAGE_LENGTH+1];
   int nbytes, i;
   printf("Receiving data..\n");
   nbytes = recv(skt, buf, MESSAGE_LENGTH, 0);
   buf[nbytes] = '\0';
   printf("Received %d bytes\n", nbytes);
}



--ELM949503248-12168-0_
Content-Type: text/plain; charset=ISO-8859-1
Content-Disposition: attachment; filename=TCPDelayTest.java
Content-Description: tmp/wave/TCPDelayTest.java
Content-Transfer-Encoding: 7bit

import java.io.*;
import java.net.*;

public class TCPDelayTest {

   final static int MESSAGE_LENGTH = 20;

   public static void main(String arguments[]) throws Exception {

      ServerSocket serverSocket = new ServerSocket(0);
      Socket sendSocket = new Socket("localhost", serverSocket.getLocalPort());
      OutputStream out = sendSocket.getOutputStream();
      Socket receiveSocket = serverSocket.accept();
      InputStream in = receiveSocket.getInputStream();

      sendSocket.setTcpNoDelay(Boolean.valueOf(arguments[0]).booleanValue());

      byte receiveBuffer[] = new byte[MESSAGE_LENGTH];
      byte sendBuffer[] = new byte[MESSAGE_LENGTH];
      for (int i = 0; i < MESSAGE_LENGTH; i++) sendBuffer[i] = (byte)'a';

      int count;
      long time1, time2;

      for (long i = 0; i < 100; i++) {
         time1 = System.currentTimeMillis();

         System.out.println("Sending data...");
         out.write(sendBuffer);
         System.out.println("Data sent.");

         System.out.println("Receiving data...");
         count = in.read(receiveBuffer);
         System.out.println(count + " byte(s) received.");

         time2 = System.currentTimeMillis();
         System.out.println("Round trip time: " + (time2 - time1));
      } 
   }
}

--ELM949503248-12168-0_--


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-questions" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20000202145409.225685DC3>