Thread: Stupid network question.

  1. #1
    Registered User
    Join Date
    Mar 2009
    Posts
    37

    Stupid network question.

    Hello guys,

    I almost don't dare to ask, but I have to.
    I was playing with sockets a quite a while, but there is one thing that makes me insane. Suppose I have a server listening on port 1234 and as a client I just simply telnet to that port. Well, I the connection is established and everything is ok.

    But when I use a tool to analyze all the socket connections on my system (in this case windose, yes I'm sorry), I have a listening port on 1234, which is the server part, and an established connection between server port 1234 and client port 1541 (which is random by the OS).

    So with the client I can still send data to the server port 1234, which works fine. But the strange thing is, I can create a new client connecting to the server also at port 1234.

    And here comes the main point. The strange thing is, on the server side it's listening on port 1234 for a new client connection, which is waiting on the accept(), but at the same time I can receive data from that same port 1234 to handle incoming data from a client.

    So how is this distinguished between a client connection request on the accept() call and some regular data from an already connected client (on another thread or process) on the recv()?

    I hope you understand my question, thank you.

  2. #2
    {Jaxom,Imriel,Liam}'s Dad Kennedy's Avatar
    Join Date
    Aug 2006
    Location
    Alabama
    Posts
    1,065
    My understanding of the handshake of TCP/IP is that after the client and server communicate the negotiation, the client begins to talk on the upper-bound port (as the socket handler threads or forks off to handle that connection).

    If this is not the case, however, the packets coming in should have identifiable markings such that the packets would be routed to the correct thread/fork.

    All of this is a shoot-from-the-hip and I'm probably wrong. . . but no-one else had jumped in, I figured I'd give you something. Google, however, is your friend.

  3. #3
    Registered User
    Join Date
    Mar 2009
    Posts
    37
    Thanks Kennedy,

    I guess there is a frame in the tcp/ip packet which contains an identifier of the socketfiledescriptor or sockethandle (whatever you call it) to identify which socket_fd the data belongs to.

    I have googled a lot and it's difficult to find the right information, you find more about the general stuff, but not the answer to my question.

    But I've found something which is more OS specific. I think the OS keeps a list of client's ipaddress and portnumber with the socket_fd. So this means when a packet arrives, the OS checks its ip and port and search in his table for associated socket_fd.

    This is what I found from a powerpoint doc:
    Question: there is one http server, there may be several http clients which sends http requests to the http server simultaneously,so there are several connections at the same with the same destination IP address, same port number: 80, and the same protocol type: TCP. How does the server distinguish these connections and process them separately?

    Answer: the way to specify the end-to-end process-to-process connection.
    Socket address: port number + IP address + protocol type
    Sender socket address: sender port number + sender IP address + protocol type
    Receiver socket address: receiver port number + receiver IP address + protocol type.
    Connection = sender socket address + receiver socket address

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Andaluz View Post
    I guess there is a frame in the tcp/ip packet which contains an identifier of the socketfiledescriptor or sockethandle (whatever you call it) to identify which socket_fd the data belongs to.
    No there is not. There is a sort of schematic of the TCP header in RFC 793 (1981):
    Code:
      0                   1                   2                   3   
        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |          Source Port          |       Destination Port        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                        Sequence Number                        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                    Acknowledgment Number                      |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |  Data |           |U|A|P|R|S|F|                               |
       | Offset| Reserved  |R|C|S|S|Y|I|            Window             |
       |       |           |G|K|H|T|N|N|                               |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |           Checksum            |         Urgent Pointer        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                    Options                    |    Padding    |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                             data                              |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    The IP header is from the same year, RFC 791
    Code:
       0                   1                   2                   3   
        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |Version|  IHL  |Type of Service|          Total Length         |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |         Identification        |Flags|      Fragment Offset    |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |  Time to Live |    Protocol   |         Header Checksum       |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                       Source Address                          |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                    Destination Address                        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                    Options                    |    Padding    |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    You can find these most easily by googling the RFC's and not "tcp/ip header".

    The socket interface deals with this, meaning it is generally opaque in network programming. If you write a packet sniffer, however, you can peel it all apart and see it in action. The last relevant aspect of an address is the port number; beyond that (eg, what thread or file descriptor is involved), that is internal to the application and there will be no trace of it in the header (unless you manually program something in; there are some small unused fields; I'm not sure how you would go about such a thing, however, considering the aforementioned opaqueness).

    Quote Originally Posted by Kennedy View Post
    If this is not the case, however, the packets coming in should have identifiable markings such that the packets would be routed to the correct thread/fork.
    Again, no. The "sequence" and "acknowledgement" number are used to keep messages sorted out by the socket API. If you did want to access the packet header yourself you could sort (further) using those, but again, anything such as a thread, fork, process id, or socket/file descriptor is totally internal to your program.
    Last edited by MK27; 05-28-2009 at 08:49 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    Registered User
    Join Date
    Mar 2009
    Posts
    37
    Thanks for your explanation MK27,

    So the tcp/ip (or the tcp alone) packet doesn't contain any information relating to socket_fd or whatever. That's why I assume the OS takes care for that. Cause when I use select() to wait for an activity on the sockets, the kernel than takes care to trigger my app about it.

    I hope you can confirm that...

  6. #6
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    A TCP connection is uniquely identified by a four-tuple ( source ip, source port, destination ip, destination port ).

    If two clients from the same host connect, the will have different source ports; unique.

    If two clients from different hosts connect, they will have different source ips; unique.

    The IP stack on the client machine ensures that no two outgoing connections to the same destination IP have the same source port number. And even if the client stack was broken, the two connections would have two lines of sequence numbers, which the server would immediately recognize as being bogus -- it would probably drop both connections.
    Last edited by brewbuck; 05-28-2009 at 09:54 AM.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  7. #7
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Andaluz View Post
    So the tcp/ip (or the tcp alone) packet doesn't contain any information relating to socket_fd or whatever. That's why I assume the OS takes care for that. Cause when I use select() to wait for an activity on the sockets, the kernel than takes care to trigger my app about it.
    Something like that; I guess the socket API is written as an interface to the OS/kernel, which does the actual networking. So, the nitty gritty details of tcp/ip are on one side of the interface (the OS side); the kernel passes data thru to your application in user-space AFTER that has been dealt with (so the application only accesses certain details distilled from the packet headers by the OS). Meaning, the internals of the user-space app (your program) are "downstream" from there; you access a port, and witness the API contains mechanisms for dealing with the selecting the port number, etc. After that, what comes in is your problem (and its involvement with file descriptors, threads, whatever). This is part of the 7 layer OSI ("Open Systems Interconnection") model; specifically it involves the last two or three layers (session -> presentation -> application). The "transport" layer is below that (so notice, on the kernel's side of the interface) -- eg, TCP. Below that is the "network" layer (eg, IP); that is where the kernel deals with incoming packets. The first two layers (data-link and physical) do not involve any process inside your computer unless it is performing some kind of router function. I'm no expert on this, but you can google "OSI model" and there is lots of info on that.

    A packet sniffer is a tool used to monitor (or spy on) the network layer as dealt with by the kernel. My suggestion that you might be able to use this to get things like the syn and ack numbers in the context of a normal socket (client or server) app is theoretical; I pretty sure that would be a weird and unnecessary thing to do.

    Really, you just have to do a better job of managing your threads and file descriptors!
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  8. #8
    Registered User
    Join Date
    Mar 2009
    Posts
    37
    Thanks guys,

    It's clear to me now. It just annoys me if I keep with a question wandering in my head.
    But now your help clarified at least the conceptual way of tcp/ip and sockets.

    If I want to sniff packets, I just use wireshark.

    Thanks, you're great, guys.

  9. #9
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Andaluz View Post
    If I want to sniff packets, I just use wireshark.
    Writing a packet sniffer is actually not that hard*. That's how I learned the OSI stuff. So you could incorporate it into a server program, but as mentioned there is probably no point.

    *google pcap, I dunno if that library works on MS, altho it probably does since I think that is what wireshark uses (pcap)
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Stupid Question Probably
    By Kyrin in forum C Programming
    Replies: 2
    Last Post: 05-07-2006, 12:51 AM
  2. Replies: 7
    Last Post: 11-04-2005, 12:17 AM
  3. Stupid Question
    By digdug4life in forum C++ Programming
    Replies: 22
    Last Post: 05-17-2005, 11:43 AM
  4. stupid, stupid question
    By xelitex in forum C++ Programming
    Replies: 5
    Last Post: 12-22-2004, 08:22 PM
  5. Stupid question: What does Debugger do?
    By napkin111 in forum C++ Programming
    Replies: 6
    Last Post: 05-02-2002, 10:00 PM