IPV4 RAW AF INET TCP server client program with Poll system call
====================================================================

.. tab-set::

    .. tab-item:: IPv4 RAW_AF_INET TCP

        * In this program, you are going to learn
        
        .. panels::
                :container: container pb-4
                :column: col-lg-12 p-2
                :card: shadow

                * How to create a Socket ?

        .. panels::
                :container: container pb-4
                :column: col-lg-12 p-2
                :card: shadow

                * How to write a data ?

        .. panels::
                :container: container pb-4
                :column: col-lg-12 p-2
                :card: shadow

                * How to read a data ?  
        
	.. panels::
                :container: container pb-4
                :column: col-lg-12 p-2
                :card: shadow

                * How to use socket APIs ?

                        * `socket <https://man7.org/linux/man-pages/man2/socket.2.html>`_

                        * `write <https://man7.org/linux/man-pages/man2/write.2.html>`_

                        * `read <https://man7.org/linux/man-pages/man2/read.2.html>`_
        .. panels::
                :container: container pb-4
                :column: col-lg-12 p-2
                :card: shadow

                Topics in this section,

                        * :ref:`IPV4 RAW_AF_INET TCP SOCKET FAQs <poll_ipv4_raw_af_inet_tcp_socket>`
                        * :ref:`Step 1: Sequence Diagram for SERVER.c <poll_ipv4_raw_af_inet_tcp_socket_server_sequence_diagram>`
                        * :ref:`Step 2: Program for Server.c <poll_ipv4_raw_af_inet_tcp_socket_server_code>`
                        * :ref:`Step 3: Compile and Execute Server.c <poll_ipv4_raw_af_inet_tcp_socket_server_side_compile_and_execute>`
                        * :ref:`Step 4: Sequence Diagram for CLIENT.c <poll_ipv4_raw_af_inet_tcp_socket_client_sequence_diagram>`
                        * :ref:`Step 5: Program for Client.c <poll_ipv4_raw_af_inet_tcp_socket_client_code>`
                        * :ref:`Step 6: Compile and Execute Client.c <poll_ipv4_raw_af_inet_tcp_socket_client_side_compile_and_execute>`
                        * :ref:`Summary <poll_ipv4_raw_af_inet_tcp_Summary>`

.. _poll_ipv4_raw_af_inet_tcp_socket:
        
.. tab-set::

        .. tab-item:: IPV4 RAW_AF_INET TCP SOCKET : FAQs

                .. panels::
                        :container: container pb-4
                        :column: col-lg-12 p-2
                        :card: shadow

                        Let us answer few basic questions in this socket

                .. panels::
                        :container: container pb-4
                        :column: col-lg-12 p-2
                        :card: shadow

                        What does ``socket(AF_INET, SOCK_RAW, IPPROTO_TCP)`` do?

                        .. dropdown:: See Answer
                                
                                This call creates a raw socket in the ``AF_INET`` address family for direct access to TCP packets.

		.. panels::
                        :container: container pb-4
                        :column: col-lg-12 p-2
                        :card: shadow

                        When is it appropriate to use ``SOCK_RAW`` sockets with TCP?

                        .. dropdown:: See Answer
                                
                                It's suitable for tasks like packet capturing, network monitoring, or 
                                implementing custom protocols where direct access to TCP packets is needed.

                .. panels::
                        :container: container pb-4
                        :column: col-lg-12 p-2
                        :card: shadow

                        Can this socket be used for regular TCP communication?

                        .. dropdown:: See Answer
                                
                                While technically possible, it's not recommended for regular 
                                communication due to increased complexity and potential security risks.

                .. panels::
                        :container: container pb-4
                        :column: col-lg-12 p-2
                        :card: shadow

                        How does a raw TCP socket differ from a regular TCP socket?

                        .. dropdown:: See Answer
                                
                                A raw TCP socket provides direct access to the TCP layer, allowing for manual packet manipulation, 
                                whereas regular TCP sockets handle packet details internally.

		.. panels::
                        :container: container pb-4
                        :column: col-lg-12 p-2
                        :card: shadow

                        What are some use cases for raw TCP sockets?

                        .. dropdown:: See Answer
                                
                                Use cases include network sniffing, packet analysis, security auditing, and developing custom network protocols.

                .. panels::
                        :container: container pb-4
                        :column: col-lg-12 p-2
                        :card: shadow

                        How can I capture and analyze TCP packets using raw sockets?

                        .. dropdown:: See Answer
                                
                                You can use the raw socket to capture TCP packets and analyze them using packet analysis tools like Wireshark.

                .. panels::
                        :container: container pb-4
                        :column: col-lg-12 p-2
                        :card: shadow

                        Is error checking needed after creating the socket?

                        .. dropdown:: See Answer
                                
                                Yes, checking for errors ensures that the socket is created successfully before proceeding with further operations.

		.. panels::
                        :container: container pb-4
                        :column: col-lg-12 p-2
                        :card: shadow

                        Why is it important to check the return value of read() and write() in socket programming?

                        .. dropdown:: See Answer
                                
                                It detects issues such as network errors or closed connections.

		.. panels::
                        :container: container pb-4
                        :column: col-lg-12 p-2
                        :card: shadow

                        What is the purpose of the poll system call?

                        .. dropdown:: See Answer
                                
                                To block and wait for activity on one or more file descriptors.

                .. panels::
                        :container: container pb-4
                        :column: col-lg-12 p-2
                        :card: shadow

                        How does poll differ from poll in terms of usability?

                        .. dropdown:: See Answer
        
                                poll is more efficient than poll for monitoring multiple file descriptors.

                .. panels::
                        :container: container pb-4
                        :column: col-lg-12 p-2
                        :card: shadow

                        What types of file descriptors can be monitored using poll?

                        .. dropdown:: See Answer

                                sockets, files, timerfd, socketpair, message_queue, Namedpipes and shared_memory.

		.. panels::
                        :container: container pb-4
                        :column: col-lg-12 p-2
                        :card: shadow
                
                        How does poll handle a set of file descriptors with different states (e.g., reading, writing, exception)?       

                        .. dropdown:: See Answer
                        
                                It uses different structures for each state in the pollfd array.

                .. panels::
                        :container: container pb-4
                        :column: col-lg-12 p-2
                        :card: shadow

                        How do you handle errors when using the poll system call?

                        .. dropdown:: See Answer

                               Check the return value for -1 to detect errors, Use perror to print error messages.

		.. panels::
                        :container: container pb-4
                        :column: col-lg-12 p-2
                        :card: shadow

                        How does poll handle a set of file descriptors with different states (e.g., reading, writing, exception)?

                        .. dropdown:: See Answer

                               Array of pollfd Structures:
                                   Before calling poll, you need to create an array of pollfd structures, 
                                   where each structure represents a file descriptor and its associated events.

                                   ``struct pollfd fds[NUM_FDS];``

                                   NUM_FDS is the number of file descriptors you want to monitor.

                               Initialize pollfd Structures:
                                   For each file descriptor you want to monitor, initialize the corresponding pollfd structure with the following information:

                                   `fd:` The file descriptor to monitor.
                                   `events:` The events of interest (e.g., POLLIN for readability, POLLOUT for writability).
                                   `revents:` Initially set to zero. After the poll call, this field is updated to indicate the events that occurred.
                                   
                                   ``fds[0].fd = fd1;``

                                   ``fds[0].events = POLLIN;``

                                   ``fds[0].revents = 0;``

                                   ``fds[1].fd = fd2;``

                                   ``fds[1].events = POLLIN;``

                                   ``fds[1].revents = 0;``

				Call poll:
                                  After initializing the pollfd array, call the poll function, providing the array, the number of file descriptors, and a timeout

                                   ``int ready_fds = poll(fds, NUM_FDS, timeout_ms);``

                                   `ready_fds` will contain the number of file descriptors that are ready.


                .. panels::
                        :container: container pb-4
                        :column: col-lg-12 p-2
                        :card: shadow

                        How does poll Checking Ready File Descriptors?

                        .. dropdown:: See Answer

                                After the poll call, loop through the pollfd array and check the revents field for each file descriptor to determine which events occurred.

                                .. code-block:: c

                                        for (int i = 0; i < NUM_FDS; ++i) {
                                                if (fds[i].revents & POLLIN) {
                                                        // File descriptor i is ready for reading
                                                }

                                                if (fds[i].revents & POLLOUT) {
                                                        // File descriptor i is ready for writing
                                                }
                                                // Check other events if needed (e.g., POLLERR, POLLHUP)
                                        }

		.. panels::
                        :container: container pb-4
                        :column: col-lg-12 p-2
                        :card: shadow

                        What does it mean if poll returns 0?

                        .. dropdown:: See Answer

                                No file descriptors are ready within the specified timeout.

.. _poll_ipv4_raw_af_inet_tcp_socket_server_sequence_diagram:

.. tab-set::            

    .. tab-item:: Step 1: Sequence Diagram for SERVER.c
        
        .. plantuml::
        
           @startuml
	   !theme spacelab
           start
           :socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
           :bind(sock_fd, (struct sockaddr *)servaddr, sizeof(struct sockaddr_in));
           :connect(sock_fd, (struct sockaddr*)client_addr, sizeof(struct sockaddr_in));
           while (while(1)) is (yes)
	   :fds[0].fd = sock_fd;
           :fds[0].events = POLLIN;
	   :poll(fds, 1, 1000);
           if (fds[0].revents & POLLIN) then (yes)
              :read(sock_fd, recvbuffer, sizeof(recvbuffer));  
              :write(sock_fd, buffer, sizeof(buffer));
           else (no)
           endif
           endwhile (CTRL+c)
           :(void)close(sock_fd);
           stop
           @enduml

.. _poll_ipv4_raw_af_inet_tcp_socket_server_code:

.. tab-set::

    .. tab-item:: Step 2 : program for server.c

        * There are many functions used in socket. We can classify those functions based on functionalities.

                * Create Socket

                * Bind Socket

                * Connect Socket

                * Poll

                * Write data_packet

                * Read data_packet

                * Close socket

        * ``socket()`` is used to create a new socket. For example,

        .. code-block:: c

                sock_fd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);        

        * ``bind()`` is used to associate the socket with a specific address and port. For example,

	.. code-block:: c

                ret = bind(sock_fd, (struct sockaddr*)servaddr, sizeof(struct sockaddr_in));
        
        * ``connect()`` is used in network programming to establish a connection from a client to a server. For example,
        
	.. code-block:: c

                ret = connect(sock_fd, (struct sockaddr*)client_addr, sizeof(struct sockaddr_in));

	* ``poll()`` is used for monitoring multiple file descriptors to see if I/O is possible on any of them.

        .. code-block:: c

                ret = poll(fds, 1, 1000);
	
	* ``read`` system call in C is commonly used to read data from a file descriptor, such as a socket. 
        
	.. code-block:: c

                ret = read(sock_fd, recvbuffer, sizeof(recvbuffer));

        * ``write`` system call in C is used to write data to a file descriptor, such as a socket. 

	.. code-block:: c

                ret = write(sock_fd, buffer, sizeof(buffer));

        * ``close`` is used to close the socket To free up system resources associated with the socket. For example,

        .. code-block:: c

                (void)close(sock_fd);

        * See the full program below,

        .. literalinclude:: ipv4_raw_af_inet_tcp/server/server.c
                :language: c
                :emphasize-lines: 115, 116, 117, 137, 138, 139, 160, 161, 162, 226, 237, 238, 259, 260, 274

.. _poll_ipv4_raw_af_inet_tcp_socket_server_side_compile_and_execute:

.. tab-set::

    .. tab-item:: Step 3: Compile and Execute server.c
        
        .. code-block:: c
                :emphasize-lines: 1, 3
                
                $ gcc -o server server.c

                $ sudo ./server 127.0.0.1

                IP Address: 127.0.0.1
                IP Address: 127.0.0.1
                checksum is c945
                Received : Hello server
                Received : Hello server
                Received : Hello server
                Received : Hello server
                Received : Hello server
                Received : Hello server
                Received : Hello server
                Received : Hello server
                Received : Hello server
                Received : Hello server
                Received : Hello server
                Received : Hello server
                Received : Hello server
                Received : Hello server
                ^C

.. _poll_ipv4_raw_af_inet_tcp_socket_client_sequence_diagram:

.. tab-set::

    .. tab-item:: Step 4 : Sequence Diagram for CLIENT.c
        
        .. plantuml::
        
           @startuml
	   !theme spacelab
           start
           :socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
           :bind(sockfd, (struct sockaddr*)clientaddr, sizeof(struct sockaddr_in));
           :connect(sockfd, (struct sockaddr*)serveraddr, sizeof(struct sockaddr_in));
	   :fds[0].fd = sockfd;
           :fds[0].events = POLLIN;
           while (while(1)) is (yes)
           :write(sockfd, buffer, sizeof(buffer));
           :poll(fds, 2, -1);
	   if (fds[0].revents & POLLIN) then (yes)
              :read(sockfd, recvbuffer, sizeof(recvbuffer));
           else (no)            
           endif
           endwhile (CTRL+c)
           :(void)close(sockfd);
           stop
           @enduml

.. _poll_ipv4_raw_af_inet_tcp_socket_client_code:

.. tab-set::

    .. tab-item:: Step 5: program for client.c

        * There are many functions used in socket. We can classify those functions based on functionalities.

                * Create Socket

                * Bind Socket

                * Connect Socket

                * Poll

                * Write data_packet

                * Read data_packet

                * Close socket

        * ``socket`` is used to create a new socket. For example,

        .. code-block:: c
                                     
                sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);

        * ``bind()`` is used to associate the socket with a specific address and port. For example,

        .. code-block:: c

	     	ret = bind(sockfd, (struct sockaddr*)clientaddr, sizeof(struct sockaddr_in));
        
	* ``connect()`` is used in network programming to establish a connection from a client to a server. For example,
                
        .. code-block:: c
        
	     	ret = connect(sockfd, (struct sockaddr*)serveraddr, sizeof(struct sockaddr_in));

	* ``poll()`` is used for monitoring multiple file descriptors to see if I/O is possible on any of them.

        .. code-block:: c

                ret = poll(fds, 2, -1);

	* ``read`` system call in C is commonly used to read data from a file descriptor, such as a socket. 

	.. code-block:: c

                ret = read(sockfd, recvbuffer, sizeof(recvbuffer));

        * ``write`` system call in C is used to write data to a file descriptor, such as a socket. 

	.. code-block:: c

                ret = write(sockfd, buffer, sizeof(buffer));

        * ``close`` is used to close the socket To free up system resources associated with the socket. For example,

        .. code-block:: c

                (void)close(sockfd);

        * See the full program below,

        .. literalinclude:: ipv4_raw_af_inet_tcp/client/client.c
                :language: c
                :emphasize-lines: 115, 116, 117, 137, 138, 139, 159, 160, 161, 228, 229, 236, 247, 248, 273
 
.. _poll_ipv4_raw_af_inet_tcp_socket_client_side_compile_and_execute:

.. tab-set::

    .. tab-item:: Step 6: Compile and Execute client.c
        
        .. code-block:: c
                :emphasize-lines: 1, 3

                $ gcc -o client client.c

                $ sudo ./client 127.0.0.1

                IP Address: 127.0.0.1
                IP Address: 127.0.0.1
                checksum is c135
                Received : Hello client
                Received : Hello client
                Received : Hello client
                Received : Hello client
                Received : Hello client
                Received : Hello client
                Received : Hello client
                Received : Hello client
                Received : Hello client
                Received : Hello client
                Received : Hello client
                Received : Hello client
                Received : Hello client
                ^C

.. tab-set::

        .. tab-item:: Enhanced Socket Flexibility with ``AF_INET`` and ``PF_INET`` Domains

                .. panels::
                        :container: container pb-4
                        :column: col-lg-12 p-2
                        :card: shadow

                        **Default Domain:**

                                By default, the socket is configured to work in the ``AF_INET`` domain, handling all types of network data.

                        **Additional Domain Support:**

                                We expand the socket's capabilities to also function in the ``PF_INET`` domain, allowing it to operate similarly to ``AF_INET``.

                        **Socket Creation:**

                                We set up a network connection point known as a socket using ``socket(PF_INET, SOCK_RAW, IPPROTO_TCP)``.

                        **Working Scenario:**
                                
                                Despite the change in domain to ``PF_INET``, the socket continues to operate the same way, handling general network data.

.. _poll_ipv4_raw_af_inet_tcp_Summary:

.. tab-set::

    .. tab-item:: Summary

        ============== ==================================================================================================================
        Socket API     Learning
        ============== ==================================================================================================================
        socket         Create a new socket
        poll           Monitor multiple file descriptors (usually sockets) for read, write, or error conditions.
	write          used to write data to a file descriptor, such as a socket. 
        read           used to read data from a file descriptor, such as a socket. 
        ============== ==================================================================================================================

.. card:: See Also

        * previous topic

                * :doc:`../../../sockets/ipv4_raw_af_inet_tcp/select/select`
        
        * current topic 
        
                * :doc:`../../../sockets/ipv4_raw_af_inet_tcp/poll/poll`

        * Next topic

                * :doc:`../../../sockets/ipv4_raw_af_inet_tcp/epoll/epoll`

        * Other sockets
                
                * :doc:`../../../sockets/ipv4_raw_af_inet_udp`
                * :doc:`../../../sockets/ipv6_af_inet6_tcp`
                * :doc:`../../../sockets/ipv6_af_inet6_udp`
                * :doc:`../../../sockets/ipv6_raw_af_inet6_icmp`
                * :doc:`../../../sockets/ipv6_raw_af_inet6_tcp`
                * :doc:`../../../sockets/ipv6_raw_af_inet6_udp`
                * :doc:`../../../sockets/ipv6_raw_af_inet6_raw`
                * :doc:`../../../sockets/raw_af_packet_raw_htons_ETH_P_ALL`
                * :doc:`../../../sockets/raw_af_packet_tcp_htons_ETH_P_ALL`
                * :doc:`../../../sockets/raw_af_packet_udp_htons_ETH_P_ALL`
        
        * Other IPCs

                * :doc:`../../../Message_queues/Message_queues`
                * :doc:`../../../NamedPipes/NamedPipes`
                * :doc:`../../../Netlink/Netlink`
                * :doc:`../../../Shared_Memory/Shared_Memory`
                * :doc:`../../../Shared_Memory_2_FDS/Shared_Memory_2_FDS`
                * :doc:`../../../SocketPair/SocketPair`
                * :doc:`../../../Timerfd/Timerfd`