Algorithms_in_C 1.0.0
Set of algorithms implemented in C.
Loading...
Searching...
No Matches
tcp_full_duplex_server.c File Reference

Server-side implementation of TCP Full Duplex Communication More...

#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Include dependency graph for tcp_full_duplex_server.c:

Macros

#define PORT   10000
 For the type in_addr_t and in_port_t For structures returned by the network database library - formatted internet addresses and port numbers For in_addr and sockaddr_in structures For macro definitions related to the creation of sockets For definitions to allow for the porting of BSD programs.
 

Functions

void error ()
 Utility function used to print an error message to stderr.
 
int main ()
 Main function.
 

Detailed Description

Server-side implementation of TCP Full Duplex Communication

Author
NVombat
See also
tcp_full_duplex_client.c

The algorithm is based on the simple TCP client and server model. However, instead of the server only sending and the client only receiving data, The server and client can both send and receive data simultaneously. This is implemented by using the fork function call so that in the server the child process can receive data and parent process can send data, and in the client the child process can send data and the parent process can receive data. It runs an infinite loop and can send and receive messages indefinitely until the user exits the loop. In this way, the Full Duplex Form of communication can be represented using the TCP server-client model & socket programming

Macro Definition Documentation

◆ PORT

#define PORT   10000

For the type in_addr_t and in_port_t For structures returned by the network database library - formatted internet addresses and port numbers For in_addr and sockaddr_in structures For macro definitions related to the creation of sockets For definitions to allow for the porting of BSD programs.

For specific bit size values of variables Variable types, several macros, and various functions for performing input and output Variable types, several macros, and various functions for performing general functions Various functions for manipulating arrays of characters

Function Documentation

◆ error()

void error ( )

Utility function used to print an error message to stderr.

It prints str and an implementation-defined error message corresponding to the global variable errno.

Returns
void
53{
54 perror("Socket Creation Failed");
55 exit(EXIT_FAILURE);
56}

◆ main()

int main ( void  )

Main function.

Returns
0 on exit

Variable Declarations

< socket descriptors - Like file handles but for sockets

< character arrays to read and store string data for communication

< basic structures for all syscalls and functions that deal with internet addresses. Structures for handling internet addresses

size of address

The TCP socket is created using the socket function

AF_INET (Family) - it is an address family that is used to designate the type of addresses that your socket can communicate with

SOCK_STREAM (Type) - Indicates TCP Connection - A stream socket provides for the bidirectional, reliable, sequenced, and unduplicated flow of data without record boundaries. Aside from the bidirectionality of data flow, a pair of connected stream sockets provides an interface nearly identical to pipes

0 (Protocol) - Specifies a particular protocol to be used with the socket. Specifying a protocol of 0 causes socket() to use an unspecified default protocol appropriate for the requested socket type

< Error if the socket descriptor has a value lower than 0 - socket wasnt created

Server Address Information

The bzero() function erases the data in the n bytes of the memory starting at the location pointed to, by writing zeros (bytes containing '\0') to that area

We bind the server_addr to the internet address and port number thus giving our socket an identity with an address and port where it can listen for connections

htons - The htons() function translates a short integer from host byte order to network byte order

htonl - The htonl() function translates a long integer from host byte order to network byte order

These functions are necessary so that the binding of address and port takes place with data in the correct format

This binds the socket descriptor to the server thus enabling the server to listen for connections and communicate with other clients

If binding is unsuccessful

This is to listen for clients or connections made to the server

The limit is currently at 5 but can be increased to listen for more connections

It listens to connections through the socket descriptor

When a connection is found, a socket is created and connection is accepted and established through the socket descriptor

Communication between client and server

The bzero() function erases the data in the n bytes of the memory starting at the location pointed to, by writing zeros (bytes containing '\0') to that area. The variables are emptied and then ready for use

The fork function call is used to create a child and parent process which run and execute code simultaneously

The child process is used to receive data and after doing so sleeps for 5 seconds to wait for the parent to send data

The parent process is used to send data and after doing so sleeps for 5 seconds to wait for the child to receive data

The server and client can communicate indefinitely till one of them exits the connection

Since the exchange of information between the server and client takes place simultaneously this represents FULL DUPLEX COMMUNICATION

Value of 0 is for child process

Parent process

Close socket

63{
64 /** Variable Declarations */
65 uint32_t sockfd,
66 conn; ///< socket descriptors - Like file handles but for sockets
67 char recvbuff[1024],
68 sendbuff[1024]; ///< character arrays to read and store string data
69 /// for communication
70
71 struct sockaddr_in server_addr,
72 client_addr; ///< basic structures for all syscalls and functions that
73 /// deal with internet addresses. Structures for handling
74 /// internet addresses
75 socklen_t ClientLen; /// size of address
76
77 /**
78 * The TCP socket is created using the socket function
79 *
80 * AF_INET (Family) - it is an address family that is used to designate the
81 * type of addresses that your socket can communicate with
82 *
83 * SOCK_STREAM (Type) - Indicates TCP Connection - A stream socket provides
84 * for the bidirectional, reliable, sequenced, and unduplicated flow of data
85 * without record boundaries. Aside from the bidirectionality of data flow,
86 * a pair of connected stream sockets provides an interface nearly identical
87 * to pipes
88 *
89 * 0 (Protocol) - Specifies a particular protocol to be used with the
90 * socket. Specifying a protocol of 0 causes socket() to use an unspecified
91 * default protocol appropriate for the requested socket type
92 */
93 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
94 {
95 error(); ///< Error if the socket descriptor has a value lower than 0 -
96 /// socket wasnt created
97 }
98
99 /**
100 * Server Address Information
101 *
102 * The bzero() function erases the data in the n bytes of the memory
103 * starting at the location pointed to, by writing zeros (bytes
104 * containing '\0') to that area
105 *
106 * We bind the server_addr to the internet address and port number thus
107 * giving our socket an identity with an address and port where it can
108 * listen for connections
109 *
110 * htons - The htons() function translates a short integer from host byte
111 * order to network byte order
112 *
113 * htonl - The htonl() function translates a long integer from host byte
114 * order to network byte order
115 *
116 * These functions are necessary so that the binding of address and port
117 * takes place with data in the correct format
118 */
119 bzero(&server_addr, sizeof(server_addr));
120 server_addr.sin_family = AF_INET;
121 server_addr.sin_port = htons(PORT);
122 server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
123
124 printf("Server is running...\n");
125
126 /**
127 * This binds the socket descriptor to the server thus enabling the server
128 * to listen for connections and communicate with other clients
129 */
130 if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
131 {
132 error(); /// If binding is unsuccessful
133 }
134 /**
135 * This is to listen for clients or connections made to the server
136 *
137 * The limit is currently at 5 but can be increased to listen for
138 * more connections
139 *
140 * It listens to connections through the socket descriptor
141 */
142 listen(sockfd, 5);
143
144 printf("Server is listening...\n");
145
146 /**
147 * When a connection is found, a socket is created and connection is
148 * accepted and established through the socket descriptor
149 */
150 conn = accept(sockfd, (struct sockaddr *)NULL, NULL);
151
152 printf("Server is connected...\n");
153
154 /**
155 * Communication between client and server
156 *
157 * The bzero() function erases the data in the n bytes of the memory
158 * starting at the location pointed to, by writing zeros (bytes
159 * containing '\0') to that area. The variables are emptied and then
160 * ready for use
161 *
162 * The fork function call is used to create a child and parent process
163 * which run and execute code simultaneously
164 *
165 * The child process is used to receive data and after doing so
166 * sleeps for 5 seconds to wait for the parent to send data
167 *
168 * The parent process is used to send data and after doing so
169 * sleeps for 5 seconds to wait for the child to receive data
170 *
171 * The server and client can communicate indefinitely till one of them
172 * exits the connection
173 *
174 * Since the exchange of information between the server and client takes
175 * place simultaneously this represents FULL DUPLEX COMMUNICATION
176 */
177 pid_t pid;
178
179 #ifdef _WIN32
180 #ifdef FORK_WINDOWS
181 pid = fork();
182 #endif
183 #else
184 pid = fork();
185 #endif
186
187 if (pid == 0) /// Value of 0 is for child process
188 {
189 while (1)
190 {
191 bzero(&recvbuff, sizeof(recvbuff));
192 recv(conn, recvbuff, sizeof(recvbuff), 0);
193 printf("\nCLIENT : %s\n", recvbuff);
194 sleep(5);
195 // break;
196 }
197 }
198 else /// Parent process
199 {
200 while (1)
201 {
202 bzero(&sendbuff, sizeof(sendbuff));
203 printf("\nType message here: ");
204 fgets(sendbuff, 1024, stdin);
205 send(conn, sendbuff, strlen(sendbuff) + 1, 0);
206 printf("\nMessage Sent!\n");
207 sleep(5);
208 // break;
209 }
210 }
211
212 /// Close socket
213 close(sockfd);
214 printf("Server is offline...\n");
215 return 0;
216}
PID Controller.
Definition pid.c:31
#define PORT
For the type in_addr_t and in_port_t For structures returned by the network database library - format...
Definition tcp_full_duplex_server.c:44
void error()
Utility function used to print an error message to stderr.
Definition tcp_full_duplex_server.c:52
Here is the call graph for this function: