Connection without a listening socket?

I’ve encountered a network problem that left me a bit puzzled.

Usually, when you want to setup a TCP connection between two sockets (let’s called them S1 and S2), you need to perform these steps on the server:

  • create S1
  • bind S1 to a port (or to a port/address, if you need to)
  • set S1 to listen for connections

on the client:

  • create S2
  • tell S2 to connect to S1

and finally, the server receives the connection attempt and accepts it to remove it from the backlog of the listening socket.

Well, apparently there’s another way, which I suspect few know about.

Check out this simple application:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace SocketTest
{
    class Program
    {
        private static IPEndPoint   a = new IPEndPoint( IPAddress.Loopback, 18000 );
        private static IPEndPoint   b = new IPEndPoint( IPAddress.Loopback, 18001 );

        static void Main(string[] args)
        {
            Thread  threadA = new Thread( ThreadA );
            Thread  threadB = new Thread( ThreadB );

            threadB.Start();
            threadA.Start();
        }

        static void ThreadA()
        {
            for(;;) {
                try {
                    Socket sock = new Socket( a.AddressFamily, SocketType.Stream, ProtocolType.Tcp );

                    sock.Bind( b );
                    sock.Connect( a );

                    Console.WriteLine( "Connected from " + b + " to " + a );

                    Thread.Sleep( Timeout.Infinite );
                }
                catch {                
                }
            }
        }

        static void ThreadB()
        {
            for(;;) {
                try {
                    Socket sock = new Socket( b.AddressFamily, SocketType.Stream, ProtocolType.Tcp );

                    sock.Bind( a );
                    sock.Connect( b );

                    Console.WriteLine( "Connected from " + a + " to " + b );

                    Thread.Sleep( Timeout.Infinite );
                }
                catch {                
                }
            }
        }
    }
}

Let’s see what happens compiling and running it:

Yes, you get a connection between the two sockets. It’s something I was never told about and I would have never expected to see. But it’s correct as per RFC 793.

I’ve found out about it when a couple of clients on a test system started connecting between themselves, while they were supposed to connect to 2 different servers on localhost. Both clients were periodically trying to connect to their server, which was down. They were creating a new socket for every attempt, without binding it, thus Windows’ TCP/IP stack assigned a sequential port number to them. Eventually, the two processes reached the configuration required for the “Simultaneous Connection Synchronization” as described in the RFC.

Interesting. I guess you live and you learn.

Leave a Reply

Your email address will not be published. Required fields are marked *