I need help for problem port to thread mapping, for example, a process have 2 threads (T1, T2)and one thread(T1) is using port x and another(T2) is using port y. Now here is the problem, how to find that which thread is using which port. Based on example, T1 -> x, T2 -> y here. I have Process ID and port number only. Solution can be in user mode or kernel but I am looking for optimized approach.

Here is my doubt - To access any port, I need to bind a socket to any unique port. Now application creates a socket object, get handle and send/receive data to/from port. While this thread is using this port none can get access to this port and no-one can get handle for this socket object. That means at a particular time only 1 thread can have socket handle and use specific port. So now in my example 2 threads are using the same scenario, My question is how to identify which thread is using which port ?

I am thinking to parse process handle table and check object attribute but I don't know how to write it in code.

For my curiosity, how is a packet transferred from the port to thread ? Any article or referrer would be appreciated.

Apart from above doubt I have some more -
1. How is it managed by OS network part ?
2. Why do I need to create a socket ? Why can't I directly send or receive data to/from any port ?
3. How is a data packet read by thread belongs to multi-Threaded process ?
4. Is it possible for a thread can perform any operation on same port which is being used by another thread belongs to the same process?

1 solution

Solution 1

Any threads can use any of the sockets inside a process. I can easily pass data to a socket from 2 threads interchangeably. I don't know the internals of current windows versions but I guess there is no such data stored for sockets. Probably there is only a lock (or maybe lockless data structure) to synchronize between multiple threads that try to access the same socket at the same time and that's it.

EDIT: In high performance network engines often a thread pool is used to serve sockets when an event occurs (incoming data available, or free space is available in the send buffer, incoming connection, ...) with one of the sockets and something has to be done with the sockets, each time a random thread is used as a servant so finding out which thread handles the socket just makes no sense, its often random.

SubratSarkar wrote:

For my curiosity, how is a packet transferred from the port to thread ? Any article or referrer would be appreciated.

When the packet comes in on your ethernet card its header is parsed. If the target address isn't your machine then the packet is routed (if your machine is configured that way). If the target address is your machine then according to the target port number the incoming data is stored in the receive buffer (size of receive buffer is configurable with setsockopt/SO_RCVBUF) of the socket object inside the OS identified by the port.
Many processes can have an open handle that reference the same socket object in the OS, and any thread of these processes that application can read out data from the receive buffer of the socket to the address space of the app. I myself never used a socket object from more than one processes but there is a function to duplicate socket handles: WSADuplicateSocket[^].

Summary: The address/port pair in the incoming packet identifies a machine(address) and a socket object inside (port) the networking part of the OS. Any application can have an open handle to that socket object (the handle is basically a process-local "reference counting pointer" to an object inside the OS) and any thread inside those applications can manipulate the socket object. When all applications close all handles to the socket object it might still remain alive for some time if it has data to send in its send buffer (search for socket linger to learn more about this) or unfinished tasks regarding the TCP protocol (shutdown, etc...).

Thanks for reply. I got your point but my concern with statement as you mentioned here -
Quote:
The address/port pair in the incoming packet identifies a machine(address) and a socket object inside (port) the networking part of the OS. Any application can have an open handle to that socket object (the handle is basically a process-local "reference counting pointer" to an object inside the OS) and any thread inside those applications can manipulate the socket object.

Here is my doubt - To access any port, I need to bind a socket to any unique port. Now application creates a socket object, get handle and send/receive data to/from port. While this thread is using this port none can get access to this port and no-one can get handle for this socket object. That means at a particular time only 1 thread can have socket handle and use specific port. So now in my example 2 threads are using the same scenario, My question is how to identify which thread is using which port ?

I am more focusing on
Quote:
a socket object inside (port) the networking part of the OS.

Apart from above doubt I have some more -
1. How is it managed by OS network part ?
2. Why do I need to create a socket ? Why can't I directly send or receive data to/from any port ?
3. How is a data packet read by thread belongs to multi-Threaded process ?
4. Is it possible for a thread can perform any operation on same port which is being used by another thread belongs to the same process?

1. When you create a socket object in the network subsystem you create the first socket handle too in your process but it isn't meaningful which of the threads performed this operation inside your process. The socket object belongs to the network system and the handles that reference it belong to the respective owner processes. No threads are involved in the ownership. Please forget about this thread thing, why is that so important for you?

I also mentioned that at the end of its lifecycle a lingering socket object might exist without any referencing socket handles in any of the applications and it still holds the port - this causes headaches when you are developing/debugging a network server and if you don't setup the linger time to zero on the listen socket and you stop the process abruptly from your debugger then you have to wait for about a minute because the socket remains bound in the network subsystem.

The socket object is managed by the network subsystem because in some cases (lingering) it has to exist without open socket handles. To find out more google for socket lingering and learn more but I give you a simple scenario to understand it more: Lets say your simple client program connects to a server, sends a few bytes and then immediately closes the socket. What happens in this case? Lets say you send just 10 bytes. You create the socket, write the 10 bytes to the send buffer of the socket object (that is adjustable, lets say its 4K by default - default is OS setting dependent) and your send() function returns immediately. You also close the socket immediately. So the network subsystem is there with a socket object without any referencing socket handles and the send buffer of the socket still contains your data (because noone guaranteed that the data was immediately sent when your send() function call returned right?). In this case your socket is lingering (if the linger setup of the socket allows this) and the OS still holds the unreferenced socket object and its associated port and tries to send the data and then disconnect from the peer gracefully according to the TCP protocol.

2. I don't know, but sending data without creating a socket just makes no sense. This socket thingy is there in the OS to provide shared use of a resource (networking) between multiple processes. If you want to mess around with the network interface directly then install a DOS operating system and mess around with what you want. :-) Windows is multitasking and applications have to follow the rules.

3. If I have a process with 10 threads and I have a single socket and the network subsystem receives 10 bytes into the receive buffer of the socket object then it might happen that I read out just one byte with each thread but of course into the address space of the same process, maybe into the same buffer.

4. When a socket object inside the network subsystem holds a port, no other sockets can be bound to the same port.