IPV6 TCP server client program with Poll system call
=====================================================

.. tab-set::

    .. tab-item:: IPv6 AF_INET6 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 bind a socket ?

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

                * How to listen a socket ?

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

                * How to connect a socket ?

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

                * How to accept a socket ?

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

                * How to send a data ?

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

                * How to recv 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>`_

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

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

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

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

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

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

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

                Topics in this section,
                        
                        * :ref:`IPV6 AF_INET6 TCP SOCKET FAQs <poll_ipv6_af_inet6_tcp_socket>`
                        * :ref:`Step 1: Sequence Diagram for SERVER.c <poll_ipv6_af_inet6_tcp_socket_server_sequence_diagram>`
                        * :ref:`Step 2: Program for Server.c <poll_ipv6_af_inet6_tcp_socket_server_code>`
                        * :ref:`Step 3: Compile and Execute Server.c <poll_ipv6_af_inet6_tcp_socket_server_side_compile_and_execute>`
                        * :ref:`Step 4:Sequence Diagram for CLIENT.c <poll_ipv6_af_inet6_tcp_socket_client_sequence_diagram>`
                        * :ref:`Step 5: Program for Client.c <poll_ipv6_af_inet6_tcp_socket_client_code>`
                        * :ref:`Step 6: Compile and Execute Client.c <poll_ipv6_af_inet6_tcp_socket_client_side_compile_and_execute>`
                        * :ref:`Summary <poll_ipv6_af_inet6_tcp_Summary>`

.. tab-set::

    .. tab-item:: Enabling IPv6 on the Loopback Interface Before Program Execution

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

                Before executing the program that relies on IPv6, enable the loopback interface for IPv6 using the following command:
 
                .. code-block:: c

                        sudo sysctl -w net.ipv6.conf.lo.disable_ipv6=0

                * This command sets the disable_ipv6 parameter to 0 for the loopback interface (lo), allowing IPv6 functionality. 
                * Ensure to use this command cautiously and consider the implications, especially on production systems. 

                * After enabling IPv6, proceed to execute your program that relies on IPv6 functionality.

.. _poll_ipv6_af_inet6_tcp_socket:

.. tab-set::

        .. tab-item:: IPV6 AF_INET6 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_INET6, SOCK_STREAM, IPPROTO_TCP)`` do?

                        .. dropdown:: See Answer
                                
                                This call creates a TCP socket in the ``AF_INET6`` (IPv6) address family.

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

                        When is it appropriate to use ``SOCK_STREAM`` with IPv6?

                        .. dropdown:: See Answer
                                
                                For reliable, connection-oriented communication.

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

                        What privileges are required to create an IPv6 TCP socket?

                        .. dropdown:: See Answer
                                
                                No special privileges.

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

                        Can ``socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP)`` be used for regular UDP communication?

                        .. dropdown:: See Answer
                                
                                No, it is designed only for TCP communication.

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

                        How does an IPv6 TCP socket differ from an IPv4 TCP socket?

                        .. dropdown:: See Answer
                                
                                IPv6 sockets handle communication using IPv6 addresses.

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

                        Can I use IPv6 TCP sockets in a mixed IPv4/IPv6 environment?

                        .. dropdown:: See Answer
                                
                                Yes, most modern systems support IPv6.

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

                        How do I specify a port number for an IPv6 TCP socket?

                        .. dropdown:: See Answer
                                
                                Set the port number in the sin6_port field.

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

                        Can I use IPv6 TCP sockets for non-blocking I/O?

                        .. dropdown:: See Answer
                                
                                Yes, use setsockopt to enable non-blocking mode.

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

                        How do I handle connection establishment with IPv6 TCP sockets?

                        .. dropdown:: See Answer
                                
                                Use the bind and listen functions.
                                
		.. panels::
                        :container: container pb-4
                        :column: col-lg-12 p-2
                        :card: shadow

                        Are there any compatibility issues with older systems when using IPv6 TCP sockets?

                        .. dropdown:: See Answer
                                
                                Yes, older systems may lack IPv6 support.

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

                        How do I handle IPv6 DNS resolution in my application?

                        .. dropdown:: See Answer
                                
                                Use functions like getaddrinfo to resolve hostnames.

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

                        How should you handle errors when using accept() in socket programming?

                        .. dropdown:: See Answer

                                Check the return value and handle errors appropriately

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

                        Why is it important to check the return value of send() and recv() 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

                        Can you use a TCP socket (SOCK_STREAM) for sending and receiving data concurrently between a client and server? 
                             
                        .. dropdown:: See Answer
                                
                                Yes, TCP sockets support bidirectional communication.

		.. 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_ipv6_af_inet6_tcp_socket_server_sequence_diagram:

.. tab-set::

    .. tab-item:: Step 1: Sequence Diagram for SERVER.c

        .. plantuml::

           @startuml
	   !theme spacelab
           start
           :socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
           :bind(tcp_server_fd, (struct sockaddr*)&tcp_addr, sizeof(tcp_addr));
           :listen(tcp_server_fd, MAX_CLIENTS);
           :tcp_client_fd = accept(tcp_server_fd, (struct sockaddr*) &tcp_addr, &tcp_addr_len);
           :fds[0].fd = tcp_client_fd;
           :fds[0].events = POLLIN;
           while (while(1)) is (yes)
           :poll(fds, MAX_CLIENTS + 1, -1);
           if (fds[0].revents & POLLIN) then (yes)
              :recv(tcp_client_fd, buffer, sizeof(buffer) - 1, 0);
              :send(tcp_client_fd, buffer, strlen(buffer), 0);
           else (no)
           endif
           endwhile (CTRL+c)
           :(void)close(tcp_client_fd);
           stop
           @enduml

.. _poll_ipv6_af_inet6_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

                * Listen Socket

                * Poll

                * Accept Socket

                * Recv data_packet

                * Send data_packet

                * Close socket

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

        .. code-block:: c

                tcp_server_fd = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);

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

        .. code-block:: c

                ret = bind(tcp_server_fd, (struct sockaddr*)&tcp_addr, sizeof(tcp_addr));

	* ``listen()`` is used to set up a socket to accept incoming connections. For example,

        .. code-block:: c

                ret = listen(tcp_server_fd, MAX_CLIENTS);               

        * ``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, MAX_CLIENTS + 1, -1);           

        * ``accept()`` is used in network programming on the server side to accept a connection request from a client. For example,

        .. code-block:: c

                tcp_client_fd = accept(tcp_server_fd, (struct sockaddr*) &tcp_addr, &tcp_addr_len);

        * ``recv``  is used in network programming to receive data from a connected socket. For example,

        .. code-block:: c
        
                len = recv(tcp_client_id, buffer, sizeof(buffer) - 1, 0);

        * ``send`` is used in network programming to send data over a connected socket. For example,

        .. code-block:: c

                ret = send(tcp_client_fd, buffer, strlen(buffer), 0);

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

        .. code-block:: c

                (void)close(tcp_client_fd);
	
	* See the full program below,

        .. literalinclude:: IPV6_AF_INET6_TCP/server/server.c
                :language: c
                :emphasize-lines: 95, 96, 111, 112, 159, 160, 161, 168, 169, 170, 178, 179, 189, 190, 191, 208, 220, 221

.. _poll_ipv6_af_inet6_tcp_socket_server_side_compile_and_execute:

.. tab-set::

    .. tab-item:: Step 3: Compile and Execute Server.c

        .. code-block:: c
                :linenos:
                :emphasize-lines: 1, 3

                $ gcc -o server server.c

                $ sudo ./server 8080 ::1

		Port: 8080
		IP Address: ::1
		Serverlistening...
		Connection Accept
		Received: HI
		Sentbuffer = HELLO
		Received: HI
		Sentbuffer = HELLO
		Received: HI
		Sentbuffer = HELLO
		Received: HI
		Sentbuffer = HELLO
		Received: HI
		Sentbuffer = HELLO
		Received: HI
		Sentbuffer = HELLO
		Received: HI
		^CCaught sigINT!

.. _poll_ipv6_af_inet6_tcp_socket_client_sequence_diagram:

.. tab-set::

    .. tab-item:: Step 4: Sequence Diagram for CLIENT.c

        .. plantuml::

           @startuml
	   !theme spacelab
           start
           :socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
           :connect(client_fd, (struct sockaddr*)&tcp_addr, tcp_addr_len);
           while (while(1)) is (yes)
           :send(client_fd, buffer, strlen(buffer), 0);
           :fds[0].fd = client_fd;
           :fds[0].events = POLLIN;
           :poll(fds, 2, -1);
           if (fds[0].revents & POLLIN) then (yes)
              :recv(client_fd, buffer, sizeof(buffer) - 1, 0); 
           else (no)
           endif
           endwhile (CTRL+c)
           :(void)close(client_fd);
           stop
           @enduml

.. _poll_ipv6_af_inet6_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

                * Connect Socket

                * Poll

                * Recv data_packet

                * Send data_packet

                * Close socket

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

        .. code-block:: c

                client_fd = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);

        * ``connect`` is used in network programming to establish a connection from a client to a server. For example,

        .. code-block:: c

                cli_connect = connect(client_fd, (struct sockaddr*)&tcp_addr, tcp_addr_len);

        * ``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);       

	* ``send`` is used in network programming to send data over a connected socket. For example,

        .. code-block:: c

                ret = send(client_fd, buffer, strlen(buffer), 0);

        * ``recv`` is used in network programming to receive data from a connected socket. For example,

        .. code-block:: c

                len = recv(client_fd, buffer, sizeof(buffer) - 1, 0);

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

        .. code-block:: c

                (void)close(client_fd);

        * See the full program below,

        .. literalinclude:: IPV6_AF_INET6_TCP/client/client.c
                :language: c
                :emphasize-lines: 79, 80, 103, 104, 155, 156, 157, 164, 165, 166, 181, 193

.. _poll_ipv6_af_inet6_tcp_socket_client_side_compile_and_execute:

.. tab-set::

    .. tab-item:: Step 6: Compile and Execute Client.c

        .. code-block:: c
                :linenos:
                :emphasize-lines: 1, 3

                $ gcc -o client client.c

                $ sudo ./client 8080 ::1

		Port: 8080
                IP Address: 127.0.0.1
                connected
                sentbuffer = HI
                Received: HELLO
                sentbuffer = HI
                Received: HELLO
                sentbuffer = HI
                Received: HELLO
                sentbuffer = HI
                Received: HELLO
                sentbuffer = HI
                Received: HELLO
                sentbuffer = HI
                Received: HELLO
                sentbuffer = HI
                Received: HELLO
                ^CCaught sigINT!

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

                $ sudo ./server 8080 ::1

                $ sudo ./client 8080 ::1

                program to run with elevated privileges, listen on port 8080, and bind to the loopback address ::1. 
                
                <port_number> <ip_address> decided by the user based on the connection.

.. tab-set::

        .. tab-item:: Enhanced Socket Flexibility with ``AF_INET6`` and ``PF_INET6`` 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_INET6`` domain, handling all types of network data.

                        **Additional Domain Support:**

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

                        **Socket Creation:**

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

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

.. _poll_ipv6_af_inet6_tcp_Summary:

.. tab-set::

    .. tab-item:: Summary

        ============== =========================================================================================
        Socket API     Learning
        ============== =========================================================================================
        socket         Create a new socket
        bind           Associate the socket with a specific address and port
        listen         Set up a socket to accept incoming connections.
        connect        Establish a connection from a client to a server.
        accept         Server side to accept a connection request from a client.
        poll           Monitor multiple file descriptors (usually sockets) for read, write, or error conditions.
        recv           Receive data from a connected socket.
        send           Send data over a connected socket.
        ============== =========================================================================================

.. card:: See Also

        * previous topic

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

        * Next topic

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

	* Other sockets
                
                * :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`