forked from codergs/TCP-UDP-DNS-Server-in-C
-
Notifications
You must be signed in to change notification settings - Fork 0
/
TCP_Client.c
184 lines (151 loc) · 7.53 KB
/
TCP_Client.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
//**************************************************************//
// //
// PROJECT: DNS DOSSIER //
// //
//**************************************************************//
// //
// CLIENT END TCP/IP APPLICATION //
// //
//**************************************************************//
#include <stdio.h> // for printf() and fprintf()
#include <sys/socket.h> // for socket(), connect(), send(), and recv()
#include <arpa/inet.h> // for sockaddr_in and inet_addr()
#include <stdlib.h> // for atoi() and exit()
#include <string.h> // for memset()
#include <unistd.h> // for close()
#include <stdbool.h> // for ip check
#include <ctype.h> // for tolower()
/* Function to validate the IP Address entered by Client */
bool isValidIpAddress(char *ipAddress)
{
struct sockaddr_in sa;
int result = inet_pton(AF_INET, ipAddress, &(sa.sin_addr));
return result != 0;
}
#define RCVBUFSIZE 100 // Size of receive buffer
//**************** Function Prototype Declarations ***************//
void DieWithError(char *errorMessage); /* Error handling function */
char * toString(char str[], int num);
//-------------------------------------------------------------------//
//*************** MAIN FUNCTION *************************//
//-------------------------------------------------------------------//
int main(int argc, char *argv[])
{
int sock; // Socket descriptor
struct sockaddr_in serverAddr; // Echo server address
unsigned short serverPort; // Echo server port
char *servIP; // Server IP address (dotted quad)
char echoString[100]; // String to send to echo server
char echoBuffer[RCVBUFSIZE]; // Buffer for echo string
unsigned long echoStringLen; // Length of string to echo
long bytesRcvd, totalBytesRcvd; // Bytes read in single recv() and total bytes read
char * action; // Type of request from client to server
char * domainName; // For Domain name argument
char * ipToAdd;
char str[2]; //= argc;
if ((argc < 4) || (argc > 6)) // Test for correct number of arguments
{
printf("\n\t\tNo of command line parametes aren't enough and proper for the request");
exit(1);
}
servIP = argv[1]; // First arg: server IP address (dotted quad)
serverPort = atoi(argv[2]); // Use given port, if any
action = argv[3];
strcpy(echoString,toString(str,argc));
strcat(echoString, "#"); // Formatting the string to be sent with "#" in between args
strcat(echoString, action);
strcat(echoString, "#"); // Check if valid action code is entered
if (atoi(action)> 6 || atoi(action) <0)
DieWithError("Invalid request code entered by the client");
switch (argc){ // Check for the number of args entered by the Client
case 5: domainName = argv[4];
strcat(echoString,domainName);
strcat(echoString,"#");
printf("\nCommand Sent: %s %s %s %s",argv[1],argv[2],argv[3],argv[4] );
break;
case 6: //To validate the IP Address format
if (isValidIpAddress(argv[5])){
domainName = argv[4];
strcat(echoString,domainName); // Concatenate the domain name to the string
strcat(echoString," ");
ipToAdd = argv[5];
strcat(echoString,ipToAdd); // Concatenate the IP to the string
strcat(echoString,"#");
printf("\nCommand Sent: %s %s %s %s %s",argv[1],argv[2],argv[3],argv[4], argv[5]);
break;
}
else
DieWithError("Invalid IP Address entered by the client");
default: printf("\nCommand Sent: %s %s %s",argv[1],argv[2],argv[3]);
break;
}
/* Create a reliable, stream socket using TCP */
if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
DieWithError("socket() failed");
/* Construct the server address structure */
memset(&serverAddr, 0, sizeof(serverAddr)); // Zero out structure
serverAddr.sin_family = AF_INET; // Internet address family
serverAddr.sin_addr.s_addr = inet_addr(servIP); // Server IP address
serverAddr.sin_port = htons(serverPort); // Server port
/* Establish the connection to the echo server */
if (connect(sock, (struct sockaddr *) &serverAddr, sizeof(serverAddr)) < 0)
DieWithError("connect() failed");
echoStringLen = strlen(echoString); // Determine input length
/* Converting all arguments to lowercase */
if (strcmp(action,"6") != 0 ){
for(int i = 0; echoString[i]; i++){
if(echoString[i]!= '#')
echoString[i] = tolower(echoString[i]);
}
}
/* Send the string to the server */
if (send(sock, echoString, echoStringLen, 0) != echoStringLen)
DieWithError("send() sent a different number of bytes than expected");
/* Receive the same string back from the server */
totalBytesRcvd = 0;
printf("\nReceived: "); // Setup to print the echoed string */
/* Receive up to the buffer size (minus 1 to leave space for
a null terminator) bytes from the sender */
while (totalBytesRcvd < RCVBUFSIZE)
{
/* Receive up to the buffer size (minus 1 to leave space for
a null terminator) bytes from the sender */
if ((bytesRcvd = recv(sock, echoBuffer, RCVBUFSIZE - 1, 0)) <= 0)
DieWithError("recv() failed or connection closed prematurely");
totalBytesRcvd += bytesRcvd; // Keep tally of total bytes
echoBuffer[bytesRcvd] = '\0'; // Terminate the string!
printf("%s", echoBuffer); // Print the echo buffer
}
printf("%s", echoBuffer); // Print the echo buffer
printf("\n"); // Print a final linefeed
close(sock); // CLOSE SOCKET
exit(0);
}
//------------------------------------------------------------------------//
//********************* MAIN FUNCTION ENDS **********************//
//------------------------------------------------------------------------//
// Die with error - Error handling function
void DieWithError(char *errorMessage)
{
perror(errorMessage);
exit(1);
}
//toString function
char * toString(char * str, int num)
{
int i, rem, len = 0, n;
n = num;
while (n != 0) // Iterates over to count the number of digits
{
len++;
n /= 10;
}
for (i = 0; i < len; i++) // Converts each digit into a character in the string
{
rem = num % 10;
num = num / 10;
str[len - (i + 1)] = rem +'0' ;
}
str[len] = '\0';
return str; // return the integer converted to String
}