Socket quirks

I have a networking problem that is more or less haunting me.

I have reduced the problem down to only a… port number!

Let me begin with the setup:
[x] I have a server, with 1gbit ethernet (Linux 2.6.18)
[x] I have a home connection with 1mbit upload (~100KB/sec upload)
[x] I send 4MB (random bytes) from the client to the server, and the server simply accepts,reads,discards the data.

When the ServerSocket is listing on port 2048, everything is well.
The (manually) interleaved STDOUT from the server and client looks (a bit) like this:


CLIENT: 95KB/sec
                                               SERVER: 93KB/sec
CLIENT: 92KB/sec
                                               SERVER: 94KB/sec
CLIENT: 94KB/sec
                                               SERVER: 97KB/sec
CLIENT: 96KB/sec
                                               SERVER: 92KB/sec
CLIENT: 93KB/sec
                                               SERVER: 92KB/sec
...

When the ServerSocket is listing on port 80, everything is b0rked.
The (manually) interleaved STDOUT from the server and client looks (a bit) like this:


CLIENT: 500KB/sec (impossible)
                                               SERVER: 37KB/sec
CLIENT: 37KB/sec
                                               SERVER: 4KB/sec
CLIENT: 19KB/sec
                                               SERVER: 8KB/sec
CLIENT: 0KB/sec
                                               SERVER: 3KB/sec
CLIENT: 72KB/sec
                                               SERVER: 103KB/sec
...

It is literally the same code, but when I change the port, everything goes belly up. The client thinks it sent 500KB in the first second, which is impossible, and after that, the connection is flaky at best, most of the time I/O over port 80 is 4-5x slower than port 2048, often gaps in traffic for 3 seconds, sometimes even dropping the connection.

I looked at the (iptables) firewall, and all is properly setup:


.........
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:22
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:80
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:110
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:443
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:2048
REJECT     all  --  0.0.0.0/0            0.0.0.0/0           reject-with icmp-port-unreachable

Naturally I cannot host the service on port 2048, as it is a publicly available HTTP server.
Note that the test-application is NOT a HTTP server, and so simple it can be considered ‘bug-free’ …


            try
            {
               ServerSocket ss = new ServerSocket(80 <---> 2048, 50, InetAddress.getByName("123.456.789.012"));
               while (true)
               {
                  final Socket s = ss.accept();

                  new Thread(new Runnable()
                  {
                     @Override
                     public void run()
                     {
                        try
                        {
                           InputStream in = new BufferedInputStream(s.getInputStream());
                           OutputStream out = s.getOutputStream();

                           byte[] buf = new byte[8 * 1024];

                           long last = System.currentTimeMillis();
                           int accum = 0;

                           while (true)
                           {
                              long now = System.currentTimeMillis();
                              int got = in.read(buf);
                              if (got == -1)
                                 throw new EOFException();
                              accum += got;

                              if (now - last > 1000L)
                              {
                                 System.out.println("accum=" + (accum / 1024) + "K");
                                 last += 1000L;
                                 accum = 0;
                              }
                           }
                        }
                        catch (IOException exc)
                        {
                           exc.printStackTrace();
                        }
                     }
                  }).start();
               }
            }
            catch (IOException exc)
            {
               exc.printStackTrace();
            }

Socket.sendBufferSize / Socket.recvBufferSize are 8K.

I’m out of ideas… :persecutioncomplex: I can’t get the TCP connection on port 80 stable and reliable to save my life! You can imagine this is critical to any webapp…

Does somebody have an idea what can cause this?

Your ISP, your server, or perhaps even your router, is intercepting port 80 sockets and attempting to “optimise” HTTP requests. Which of course, you’re not doing. Best find out which of the 3 it is.

Cas :slight_smile:

I’ve never been able to get anything working over port 80, for whatever reason. A couple times I figured I would try to use it so that I wouldn’t need to worry about firewalls, but no dice. I think you might need to treat it differently in order to get the OS to allow you to use it, or something. Otherwise I don’t know exactly why.

As a note, I never tried with a totally “bug free” server (I’ve only given it a go from my personal machines), but yeah port 80 has never been happy for me.

Good suggestion. It’s probably that… but the thing is, the original application that had severe problems, was actually using the HTTP protocol, and I run this also on another server, provided by the same ISP, in the same rack (or near it), and it works flawlessly. I also run it on 2 more servers hosted in other datacenters by other ISPs… I bet the only thing I can do is creating a support ticket… >:( This is ridiculous, I lost so much time over this, narrowing it down.

My isp hacks the hell out of port 80. So i am betting princec is correct. I get an initial burst on port 80 well above my average quoted bandwidth, which then stalls before settling down at the quoted rate some many seconds later. I know this is not the router in my case as i have tested a few, and i set them up myself.

This is pretty common, because for most people this make the “web” much more responsive. Most pages fit in the initial burst.

That initial (fake) burst wouldn’t be that bad, but after that, the connection is unreliable at best. As said, it hardly manages to transfer a few MB, it will get stuck at 0KB/sec for minutes, sometimes, then resuming at a few KB/sec. It’s hacked beyond being usable. It never ‘settles’.

I’m also not really sure how it makes the websites faster. Maybe for downloading, but remember I’m uploading using POST. The website can only respond when it received the full message. The client only thinks it sent 500KB in a split second, but the server has only a few bytes. So the server won’t be able to respond any faster (and in my case, it will sometimes even timeout after a few minutes).

I have this feeling that it’s something bad my datacenter-ISP configured, as it works fine in other datacenters, with other datacenter-ISPs (home and office ISP have exactly the same problem with that server on that port).

Currently I run a single application on both ports (created 2 serversockets) and I send the POST requests to port 2048, and the GET requests to port 80. Works flawlessly, but it’s a dirty hack.

Anyway, I sent the support ticket, and it will be handled ‘soon’. Let’s see what they come up with.

Hm… the ISP at the datacenter has no clue, and they say they don’t do HTTP throttling or traffic shaping.

So I thought it must be the home/office ISPs (despite that they are different companies), so I did some further testing on a bunch of computers.

Home [PC1 Vista]: problems on port 80
Office [PC2 WinXP]: problems on port 80
Office [PC3 WinXP]: works perfectly! :o
Office [PC4 Win7]: problems on port 80

So PC2 and PC3 are almost idential, both running WinXP, attached to the same switch, and one is stable on port 80, and the other is not (both are stable on port 2048).

It seems like some obscure setting in the PCs is causing this…

Wow, that sucks… I’d be very interested to find out the reasons if you ever get this working.