Download as pdf or txt
Download as pdf or txt
You are on page 1of 23

University of Dhaka

Department of Computer Science and Engineering

CSE-3111 : Computer Networking Lab

Lab Report 02 : Introduction to Client-Server Communication using


Socket Programming — Simulating an ATM Machine Operation

Submitted By:

Name : Md. Rafi Al sad Rifat


Roll No : 24

Name : Md. Rokonuzaman Rokon


Roll No : 08

Submitted On :

February 01, 2024

Submitted To :

Dr. Md. Abdur Razzaque

Md Mahmudur Rahman

Md. Ashraful Islam

Md. Fahim Arefin


1 Experiment Introduction
This experiment focuses on establishing a TCP connection between a client
and server using socket programming. The goal is to simulate an ATM
machine operation, where the client sends requests to the server, and the
server processes these requests, performing operations such as capital letter
to small letter conversion, checking for prime or palindrome numbers, and
handling ATM transactions like verifying a user’s card, querying account
balance, and making withdrawals.

2 Theory of the experiment:


• TCP Connection Establishment: The experiment begins with the
establishment of a TCP connection between a server process on host A
and a client process on host B. This involves creating sockets, binding
them to specific addresses and ports, and initiating the connection.

• Basic Operations on Server: The server process performs two ba-


sic operations requested by the client: Capital letter to small letter
conversion for a line of text and Checking whether an integer provided
by the client is a prime number or a palindrome.

• Non-idempotent Operation with Exactly-Once Semantics: The


experiment introduces a non-idempotent operation using exactly-once
semantics to handle failures in request messages, response messages,
and process execution.Designing an application-level protocol for an
ATM and a bank’s centralized server to verify user credentials, query
account balance, and make withdrawals. Enhancing the protocol to
handle errors related to both request and response messages, ensuring
reliability in communication.

• Protocol Specification: The protocol involves defining messages


exchanged between the ATM and the bank’s centralized server, spec-
ifying actions taken on message transmission and receipt. It covers
scenarios like insufficient funds during a withdrawal.

• Sketching Protocol Operation: A sketch illustrates the step-by-


step operation of the protocol for a simple withdrawal with no errors.

• Handling Errors: The enhanced protocol addresses errors related to


both request and response messages, ensuring robustness in the client-

1
server communication. This includes error handling for situations like
network disruptions or incorrect user input.

2.1 Objectives
The objectives of the experiment are to introduce students to client-server
communication using socket programming by establishing a TCP connection
between a server process on one host and a client process on another. The
experiment aims to implement basic server operations such as letter conver-
sion and checking for prime numbers or palindromes in response to client
requests. Additionally, students are expected to design a non-idempotent
operation with exactly-once semantics, developing an application-level pro-
tocol for an automatic teller machine (ATM) and a bank’s centralized server.
The protocol should handle user card verification, account balance queries,
and withdrawals, with a focus on error handling in both request and re-
sponse messages. Through this hands-on experience, students gain practi-
cal insights into networking concepts, protocol design, and the application
of exactly-once semantics in client-server communication.

3 Tools Used
• Operating System : Linux(Ubuntu 22.04Lts)

• Terminal Emulator : GNOME Terminal

• IDE : VS CODE

4 particular operation perform in the server


4.1 server code for uppercase , palindrom , prime

1
2 // / A Java program for a Server
3 import java . net .*;
4 import java . io .*;
5 import java . util .*;
6
7 public class Server {
8 // initialize socket and input stream
9 private Socket socket = null ;
10 private ServerSocket server = null ;
11 private DataInputStream in = null ;

2
12 private DataOutputStream out = null ;
13 private int account_balance = 30000;
14
15 public static boolean isPrime ( int n ) {
16 if ( n == 2)
17 return true ;
18
19 for ( int i = 2; i <= n / 2; i ++) {
20 if ( n % i == 0) {
21 return false ;
22 }
23 }
24
25 return true ;
26 }
27
28 public static boolean isPalindrome ( String message ) {
29 int size = message . length () ;
30
31 StringBuilder reversed = new StringBuilder ( message ) .
reverse () ;
32 String result = reversed . toString () ;
33
34 if ( result . equals ( message ) ) {
35 return true ;
36 }
37
38 return false ;
39 }
40
41 // constructor with port
42 public Server2 ( int port ) {
43 // starts server and waits for a connection
44 try {
45 server = new ServerSocket ( port ) ;
46 System . out . println ( " Server started " ) ;
47
48 System . out . println ( " Waiting for a client ... " ) ;
49
50 socket = server . accept () ;
51 System . out . println ( " Client accepted " ) ;
52
53 // takes input from the client socket
54 in = new DataInputStream (
55 new BufferedInputStream ( socket .
getInputStream () ) ) ;
56
57 out = new DataOutputStream ( socket . getOutputStream ()
);

3
58
59 String line = " " ;
60 boolean success = false ;
61
62 // reads message from client until " Over " is sent
63
64 // start time :
65
66 long start_time = System . currentTimeMillis () ;
67 while (! line . equals ( " Over " ) ) {
68 try {
69
70 line = in . readUTF () ;
71 System . out . println ( " message from client : "
+ line ) ;
72
73 String [] parts = line . split ( " \\ s + " ) ;
74
75 String operation = parts [0];
76 String operand = parts [1];
77 if ( operation . equals ( " uppercase " ) ) {
78 line = operand ;
79 line = line . toUpperCase () ;
80
81 } else if ( operation . equals ( " prime " ) ) {
82 int number = Integer . parseInt ( operand ) ;
83 boolean flag = isPrime ( number ) ;
84
85 if ( flag ) {
86 line = number + " is a prime number
";
87 } else {
88 line = number + " is not a prime
number " ;
89 }
90 } else if ( operation . equals ( " palindrome " ) )
{
91 boolean flag = isPalindrome ( operand ) ;
92
93 if ( flag ) {
94 line = operand + " is a palindrome "
;
95
96 } else {
97 line = operand + " is not
palindrome " ;
98 }
99
100 } else if ( operation . equals ( " withdraw " ) ) {

4
101
102 Random random = new Random () ;
103
104 int randomNumber = random . nextInt (100)
+1 ;
105 int number = Integer . parseInt ( operand ) ;
106
107 if ( randomNumber >4 && randomNumber <80)
108 {
109 line = " Transaction failure " ;
110
111 } else
112 {
113 if ( account_balance >= number ) {
114 account_balance =
account_balance - number ;
115 line = number + " has been
withdrawn from your account . Your current balance is " +
account_balance ;
116 } else {
117 line = " You donot have
sufficient balanace to withdraw " ;
118 }
119 // success = true ;
120 }
121 } else if ( operation . equals ( " deposit " ) ) {
122 int number = Integer . parseInt ( operand ) ;
123
124 Random random = new Random () ;
125
126 int randomNumber = random . nextInt (100)
+1 ;
127
128 if ( randomNumber >4 && randomNumber <80)
129 {
130 line = " deposite failure " ;
131 }
132 else
133 {
134 account_balance = account_balance +
number ;
135 line = number + " has been
deposited to your account . Your current balance is " +
account_balance ;
136 success = true ;
137 }
138
139 }
140 out . writeUTF ( line ) ;

5
141 if ( success ) break ;
142
143 } catch ( IOException i ) {
144 System . out . println ( i ) ;
145 }
146 }
147
148 // last time :
149
150 long end_time = System . currentTimeMillis () ;
151
152 // System . out . println ( end_time - start_time ) ;
153
154
155 System . out . println ( " Closing connection " ) ;
156
157 // close connection
158 socket . close () ;
159 in . close () ;
160 out . close () ;
161 } catch ( IOException i ) {
162 System . out . println ( i ) ;
163 }
164 }
165
166 public static void main ( String args []) {
167 Server2 server = new Server (5555) ;
168 }
169 }
170 // rifat

4.2 client code uppercase , palindrom , prime

1
2 // A Java program for a Client
3 import java . net .*;
4 import java . util . Scanner ;
5 import java . io .*;
6 import java . util . Random ;
7
8 public class Client2 {
9 // initialize socket and input output streams
10 private Socket socket = null ;
11 private DataInputStream input = null ;
12 private DataInputStream input_server = null ;
13 private DataOutputStream out = null ;
14
15 // constructor to put ip address and port
16 public Client ( String address , int port ) {

6
17 // establish a connection
18 try {
19 socket = new Socket ( address , port ) ;
20 System . out . println ( " Connected " ) ;
21 // takes input from terminal
22 input = new DataInputStream ( System . in ) ;
23 input_server = new DataInputStream ( socket .
getInputStream () ) ;
24
25 // sends output to the socket
26 out = new DataOutputStream ( socket . getOutputStream ()
);
27 } catch ( Unknow nHostException u ) {
28 System . out . println ( u ) ;
29 } catch ( IOException i ) {
30 System . out . println ( i ) ;
31 }
32 // string to read message from input
33 // System . out . println (" Which operation and number do
you want ?") ;
34
35 String line = " " ;
36 String message_ from_server = " " ;
37
38 // keep reading until " Over " is input
39 // input terminal theke na niye direct ekhan theke
pathacci
40
41
42 Scanner sc = new Scanner ( System . in ) ;
43
44
45
46 message_from_server = " " ;
47
48
49 while (! line . equals ( " Over " ) ) {
50 try
51 {
52 System . out . println ( " which operation do you want to
perform , uppercase , prime , palindrom , withdraw , deposit " )
;
53
54 line = sc . nextLine () ;
55 out . writeUTF ( line ) ;
56 message_from_server = input_server . readUTF () ;
57 System . out . println ( " Response from server : " +
message_from_server ) ;
58 }

7
59 catch ( IOException i ) {
60 System . out . println ( i ) ;
61 }
62 }
63
64
65
66
67 // close the cnnection
68 try {
69 out . writeUTF ( line ) ;
70 input . close () ;
71 input_server . close () ;
72 out . close () ;
73 socket . close () ;
74 } catch ( IOException i ) {
75 System . out . println ( i ) ;
76 }
77 }
78
79 public static void main ( String args []) {
80 Client2 client = new Client ( " localhost " , 5555) ;
81 }
82
83 }

Figure 1: client is connected to server

4.3 uppercase , prime and palindrom operation :


• Uppercase Operation Explained:The code includes a section for
the ”uppercase” operation, where the server receives a message from
the client requesting the conversion of a given string to uppercase. It
parses the client’s message, extracts the operation identifier (”upper-
case”), and the operand (the string to be converted).
The server then transforms the operand to uppercase using the toUp-
perCase() method and sends the result back to the client. This section

8
Figure 2: Terminal output of server response for uppercase , palindrome and
prime operation

demonstrates the handling of a simple string manipulation operation


in response to a client request.

• Prime and Palindrome Operation: The server also handles oper-


ations related to prime numbers and palindromes. For the ”prime” op-
eration, the server checks if a given number is prime using the isPrime
function, and based on the result, it constructs a response indicating
whether the number is a prime or not. Similarly, for the ”palindrome”
operation, the server checks if a given string is a palindrome using
the isPalindrome function. It then constructs a response indicating
whether the string is a palindrome or not. These sections showcase
the incorporation of mathematical and string-related computations in
response to client requests.

• Withdraw and deposit operation: The code includes functionality


for handling financial transactions such as withdrawals and deposits.
For the ”withdraw” operation, the server simulates a banking scenario,
generating a random number to determine the success or failure of the
transaction. If successful, it deducts the specified amount from the
account balance; otherwise, it informs the client of a transaction fail-
ure. The ”deposit” operation similarly simulates success or failure,

9
Figure 3: Terminal output of server response for uppercase , palindrome and
prime operation

and upon success, it adds the specified amount to the account bal-
ance. These sections illustrate the implementation of transactional
operations with simulated success or failure conditions in response to
client requests.

4.4 ATM Machine Operation : Server code

1
2 // / A Java program for a Server
3 import java . net .*;
4 import java . io .*;
5 import java . util .*;
6
7 public class Server {
8 // initialize socket and input stream
9 private Socket socket = null ;
10 private ServerSocket server = null ;
11 private DataInputStream in = null ;
12 private DataOutputStream out = null ;
13 private int account_balance = 30000;
14
15 public static boolean isPrime ( int n ) {
16 if ( n == 2)

10
17 return true ;
18
19 for ( int i = 2; i <= n / 2; i ++) {
20 if ( n % i == 0) {
21 return false ;
22 }
23 }
24
25 return true ;
26 }
27
28 public static boolean isPalindrome ( String message ) {
29 int size = message . length () ;
30
31 StringBuilder reversed = new StringBuilder ( message ) .
reverse () ;
32 String result = reversed . toString () ;
33
34 if ( result . equals ( message ) ) {
35 return true ;
36 }
37
38 return false ;
39 }
40
41 // constructor with port
42 public Server ( int port ) {
43 // starts server and waits for a connection
44 try {
45 server = new ServerSocket ( port ) ;
46 System . out . println ( " Server started " ) ;
47
48 System . out . println ( " Waiting for a client ... " ) ;
49
50 socket = server . accept () ;
51 System . out . println ( " Client accepted " ) ;
52
53 // takes input from the client socket
54 in = new DataInputStream (
55 new BufferedInputStream ( socket .
getInputStream () ) ) ;
56
57 out = new DataOutputStream ( socket . getOutputStream ()
);
58
59 String line = " " ;
60 boolean success = false ;
61
62 // reads message from client until " Over " is sent

11
63
64 // start time :
65
66 long start_time = System . currentTimeMillis () ;
67 while (! line . equals ( " Over " ) ) {
68 try {
69
70 line = in . readUTF () ;
71 System . out . println ( " message from client : "
+ line ) ;
72
73 String [] parts = line . split ( " \\ s + " ) ;
74
75 String operation = parts [0];
76 String operand = parts [1];
77 if ( operation . equals ( " uppercase " ) ) {
78 line = operand ;
79 line = line . toUpperCase () ;
80
81 } else if ( operation . equals ( " prime " ) ) {
82 int number = Integer . parseInt ( operand ) ;
83 boolean flag = isPrime ( number ) ;
84
85 if ( flag ) {
86 line = number + " is a prime number
";
87 } else {
88 line = number + " is not a prime
number " ;
89 }
90 } else if ( operation . equals ( " palindrome " ) )
{
91 boolean flag = isPalindrome ( operand ) ;
92
93 if ( flag ) {
94 line = operand + " is a palindrome "
;
95
96 } else {
97 line = operand + " is not
palindrome " ;
98 }
99
100 } else if ( operation . equals ( " withdraw " ) ) {
101
102 Random random = new Random () ;
103
104 int randomNumber = random . nextInt (10) +1
;

12
105 int number = Integer . parseInt ( operand ) ;
106
107 if ( randomNumber >4 && randomNumber <8)
108 {
109 line = " Transaction failure " ;
110
111 } else
112 {
113 if ( account_balance >= number ) {
114 account_balance =
account_balance - number ;
115 line = number + " has been
withdrawn from your account . Your current balance is " +
account_balance ;
116 } else {
117 line = " You donot have
sufficient balanace to withdraw " ;
118 }
119 // success = true ;
120 }
121 } else if ( operation . equals ( " deposit " ) ) {
122 int number = Integer . parseInt ( operand ) ;
123
124 Random random = new Random () ;
125
126 int randomNumber = random . nextInt (10) +1
;
127
128 if ( randomNumber >4 && randomNumber <8)
129 {
130 line = " deposite failure " ;
131 }
132 else
133 {
134 account_balance = account_balance +
number ;
135 line = number + " has been
deposited to your account . Your current balance is " +
account_balance ;
136 success = true ;
137 }
138
139 }
140 out . writeUTF ( line ) ;
141 if ( success ) break ;
142
143 } catch ( IOException i ) {
144 System . out . println ( i ) ;
145 }

13
146 }
147
148 // last time :
149
150 long end_time = System . currentTimeMillis () ;
151
152 // System . out . println ( end_time - start_time ) ;
153
154
155 System . out . println ( " Closing connection " ) ;
156
157 // close connection
158 socket . close () ;
159 in . close () ;
160 out . close () ;
161 } catch ( IOException i ) {
162 System . out . println ( i ) ;
163 }
164 }
165
166 public static void main ( String args []) {
167 Server server = new Server (5555) ;
168 }
169 }
170 // rifat

4.5 ATM Machine Operation : Client code

1
2 // A Java program for a Client
3 import java . net .*;
4 import java . util . Scanner ;
5 import java . io .*;
6 import java . util . Random ;
7
8 public class Client {
9 // initialize socket and input output streams
10 private Socket socket = null ;
11 private DataInputStream input = null ;
12 private DataInputStream input_server = null ;
13 private DataOutputStream out = null ;
14
15 // constructor to put ip address and port
16 public Client ( String address , int port ) {
17 // establish a connection
18 try {
19 socket = new Socket ( address , port ) ;
20 System . out . println ( " Connected " ) ;
21 // takes input from terminal

14
22 input = new DataInputStream ( System . in ) ;
23 input_server = new DataInputStream ( socket .
getInputStream () ) ;
24
25 // sends output to the socket
26 out = new DataOutputStream ( socket . getOutputStream ()
);
27 } catch ( Unknow nHostException u ) {
28 System . out . println ( u ) ;
29 } catch ( IOException i ) {
30 System . out . println ( i ) ;
31 }
32 // string to read message from input
33 // System . out . println (" Which operation and number do
you want ?") ;
34
35 String line = " " ;
36 String message_ from_server = " " ;
37
38 // keep reading until " Over " is input
39 // input terminal theke na niye direct ekhan theke
pathacci
40
41
42 Scanner sc = new Scanner ( System . in ) ;
43
44
45 System . out . println ( " which operation do you want to
perform " ) ;
46 line = sc . nextLine () ;
47 message_from_server = " Transaction failure " ;
48
49 long start_time = System . currentTimeMillis () ;
50 int ct = 0 ;
51 while ( message_from_server . equals ( " Transaction failure "
)) {
52 try {
53
54 Random random = new Random () ;
55 int randomNumber = random . nextInt (100) +1 ;
56 if ( randomNumber >4 && randomNumber <80)
57 {
58 System . out . println ( " error withdraw message
reached to destination " ) ;
59 }
60 else
61 {
62 out . writeUTF ( line ) ;
63 mes sage_from_server = input_server . readUTF

15
() ;
64 System . out . println ( " Response from server :
" + message_from_server ) ;
65 }
66
67
68 ct ++ ;
69
70 } catch ( IOException i ) {
71 System . out . println ( i ) ;
72 }
73 }
74 long end_time = System . currentTimeMillis () ;
75 System . out . println ( " withdraw operation will take time "
+ ( end_time - start_time ) + " msec number of try : " + ct )
;
76
77
78
79
80 System . out . println ( " perform deposite operation : " ) ;
81 line = sc . nextLine () ;
82 message_from_server = " deposite failure " ;
83
84 start_time = System . currentTimeMillis () ;
85 ct = 0 ;
86
87 while ( message_from_server . equals ( " deposite failure " ) ) {
88 try {
89
90 Random random = new Random () ;
91 int randomNumber = random . nextInt (100) +1;
92 if ( randomNumber >4 && randomNumber <80)
93 {
94 System . out . println ( " error deposite message
to destination " ) ;
95 }
96 else
97 {
98 out . writeUTF ( line ) ;
99 mes sage_from_server = input_server . readUTF
() ;
100 System . out . println ( " Response from server :
" + message_from_server ) ;
101
102 }
103 ct ++ ;
104
105

16
106 } catch ( IOException i ) {
107 System . out . println ( i ) ;
108 }
109 }
110 end_time = System . currentTimeMillis () ;
111 System . out . println ( " deposite operation will take time "
+ ( end_time - start_time ) + " msec number of try " + ct ) ;
112
113
114 // close the connection
115 try {
116 input . close () ;
117 input_server . close () ;
118 out . close () ;
119 socket . close () ;
120 } catch ( IOException i ) {
121 System . out . println ( i ) ;
122 }
123 }
124
125 public static void main ( String args []) {
126 Client client = new Client ( " localhost " , 5555) ;
127 }
128
129 }

• Client Initialization and Connection: The provided Java code


defines a client program that communicates with a server using sockets.
The client establishes a connection with the server by creating a socket
with a specified IP address (”localhost” in this case) and port number
(5555). It sets up input and output streams for communication with
the server. The client uses a DataInputStream to read input from the
terminal and another DataInputStream to receive messages from the
server.Additionally, it utilizes a DataOutputStream to send output
to the server. Upon successful connection, the client prompts the
user for the desired operation (withdraw or deposit) and initiates the
corresponding interaction with the server.

• Withdraw Operation:The client implements the withdrawal oper-


ation, where it prompts the user for the desired operation and sends
the request to the server.
The withdrawal is simulated with a random number generator deter-
mining whether the transaction succeeds or fails. If successful, the
client receives a response from the server, prints it, and measures the
time taken for the operation. If the transaction fails, the client retries

17
Figure 4: Terminal output of server response for withdraw operation

Figure 5: Terminal output of server response for withdraw operation

until success. The code provides insights into handling transactional


operations and the potential retries needed for a successful transaction.

• Deposit Operation: Similar to the withdrawal operation, the client


also implements the deposit operation. It prompts the user for the de-
posit operation, sends the request to the server, and simulates success
or failure with a random number generator.
The client continues to retry until a successful deposit occurs, and
it prints the server’s responses and measures the time taken for the
deposit operation. This section of the code illustrates the handling of
another financial transaction operation in conjunction with the server.

18
Figure 6: Terminal output of server response for deposite operation

Figure 7: Terminal output of server response for deposite operation

5 Error handling:
Here we try to plot a graph of error percentage vs time . For particular
operation , we track how much try will need to be successfull a operation
. Then we calculate error percentage by the flowing equation : (number of
failure try)/number of total try . And also takeing time for a operation to
be successfull .

19
Figure 8: error vs time for withdraw operation

Figure 9: error vs time for deposite operation

6 Discussion :
In this lab report we try to figure out how communicate packets through
TCP/IP protocle . We normally use same computer for communication
20
. So sending time and receiving time will be very small . And we also
try to figure out How TCP/IP protocle internally drop a packet when
it corrupted by error . To visualize this thing , we generate a random
number at the time of sending from client side and at the time of re-
ceiving to serverside . when generted random number is in a particular
range(0¡random¡40) ,then drop the packet from client side(means we are
not sending message to server ) . Again generted random number is in
another particular range(60¡random¡100) ,then drop the packet from server
side(means we are sending error message to client side ) . if any packet is
dropped . it will send this packet repeatedly .
The provided Java code consists of a client-server system that facil-
itates communication through sockets, implementing operations such as
withdrawal and deposit within a simulated banking scenario. The server
is designed to handle diverse client requests, ranging from string manipula-
tions like converting text to uppercase to more complex operations such as
checking for prime numbers, palindromes, and managing financial transac-
tions.
The server’s modular design with separate functions for primality and
palindrome checks enhances code readability and maintainability. Addition-
ally, the server introduces a random element to simulate transaction success
or failure, providing a more dynamic and realistic user experience.
On the client side, the program initiates a connection to the server,
prompting the user to select between withdrawal and deposit operations.
The client implements a retry mechanism, simulating multiple attempts until
a successful transaction occurs. This approach is beneficial for scenarios
where network conditions or server response times might cause temporary
failures.
Both the server and client incorporate timestamping to measure the time
taken for each operation. This enables performance monitoring and allows
for analysis of the time complexity of different operations.
However, the code could benefit from enhanced error handling, especially
in scenarios where unexpected issues may arise during communication or in-
put processing. Moreover, the use of predefined strings like ”Transaction
failure” or ”deposit failure” may limit the flexibility and clarity of com-
munication between the client and server. Introducing a more structured
response system could enhance the overall robustness of the system.
In summary, the presented code provides a foundation for building a
client-server application with socket communication, demonstrating the han-
dling of diverse operations and incorporating randomness for realistic trans-
action simulations. Future improvements could focus on refining error han-

21
dling, expanding functionality, and optimizing code readability.

References
[1] Computer networking : a top-down approach 6th ed.

[2] https://www.javatpoint.com/socket-programming

[3] https://www.digitalocean.com/community/tutorials/
java-socket-programming-server-client

[4] https://www.geeksforgeeks.org/socket-programming-in-java/

22

You might also like