线程实验报告
进程(线程)同步和互斥实验报告

进程(线程)同步和互斥实验报告操作系统实验报告课程名称操作系统实验名称进程(线程)的同步与互斥成绩学生姓名作业君专业软件工程班级、学号同组者姓名无实验日期2021一、实验题目: : 进程(线程)的同步与互斥二、实验目的:自行编制模拟程序,通过形象化的状态显示,加深理解进程的概念、进程之间的状态转换及其所带来的 PCB 内容、组织的变化,理解进程与其 PCB 间的一一对应关系。
1.掌握基本的同步与互斥算法,理解生产者消费者模型。
2.学习使用 Windows 中基本的同步对象,掌握相关 API 的使用方法。
3.了解 Windows 中多线程的并发执行机制,实现进程的同步与互斥三、实验内容与要求:1.实验内容以生产者/消费者模型为依据,在 Windows 环境下创建一个控制台进程,在该进程中创建 n 个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。
2.实验要求学习并理解生产者/消费者模型及其同步/互斥规则;学习了解 Windows 同步对象及其特性;熟悉实验环境,掌握相关 API 的使用方法;设计程序,实现生产者/消费者进程(线程)的同步与互斥;四、算法描述(含数据结构定义)或流程图#include <Windows.h> #include <iostream> #include<stdio.h> #include <math.h> #include <stdlib.h> #include <time.h> using namespace std;#define MA__THREAD_NUM 64//最大线程数 #define INTE_PER_SEC 1000//延迟时间的毫秒值 const int SIZE_OF_BUFFER = 10;//缓冲区长度 int ProductID = 0;//产品号 int ConsumeID = 0;//将被消耗的产品号 int in = 0;//产品进缓冲区时的缓冲区下标 int out = 0;//产品出缓冲区时的缓冲区下标 bool running = true;//判断程序能否继续执行的逻辑值 intg_buffer[SIZE_OF_BUFFER];//缓冲区是个循环队列 HANDLE g_hMute_;//公有信号量,用于线程间的互斥 HANDLEg_hFullSemaphore;//生产者的私有信号量,当缓冲区满时迫使生产者等待HANDLE g_hEmptySemaphore;//消费者的私有信号量,当缓冲区空时迫使消费者等待//定义一个结构体用于存储线程的信息 struct ThreadInfo {int serial;//线程号char entity;//线程类别(生产者或消费者)double delay;//等待时间double persist; //操作时间 };//生产者 void Producer(void_p) {//定义变量用于存储当前线程的信息DWORD m_delay;DWORD m_persist;int m_serial;//从参数中获得信息m_serial = ((ThreadInfo_)(p))->serial;m_delay = (DWORD)(((ThreadInfo_)(p))->delay _INTE_PER_SEC);m_persist = (DWORD)(((ThreadInfo_)(p))->persist _INTE_PER_SEC);while (running){//P 操作cout << “生产者线程” << m_serial << “ 请求生产.” << endl;WaitForSingleObject(g_hEmptySemaphore, INFINITE);cout << “生产者线程” << m_serial << “ 请求独占缓冲区.” << endl;WaitForSingleObject(g_hMute_, INFINITE);Sleep(m_delay);//延迟等待//生产一个产品cout << “生产者线程”<< m_serial << “ 生产” << ++ProductID << “ 号产品成功.” << endl;cout << “生产者线程” << m_serial << “ 请求将产品” << ProductID << “ 投入缓冲区.” << endl;//把新生产的产品放入缓冲区g_buffer[in] = ProductID;in = (in +1)%SIZE_OF_BUFFER;Sleep(m_persist);//操作等待cout << “生产者线程” << m_serial << “ 将产品” << ProductID << “ 投入缓冲区中成功.” << endl;//输出缓冲区当前的状态cout << “____________________________” << endl<< “\n 当前缓冲区情况如图(■代表已有产品,□代表没有产品):” << endl;for (int i = 0;i < SIZE_OF_BUFFER;++i){if (g_buffer[i] != 0)cout << “■”;elsecout << “□”;}cout << “\n\n____________________________\n” << endl;//V 操作ReleaseMute_(g_hMute_);ReleaseSemaphore(g_hFullSemaphore, 1, NULL);} }//消费者 void Consumer(void_p) {DWORD m_delay;DWORD m_persist;int m_serial;//从参数中获得信息m_serial = ((ThreadInfo_)(p))->serial;m_delay = (DWORD)(((ThreadInfo_)(p))->delay _INTE_PER_SEC);m_persist = (DWORD)(((ThreadInfo_)(p))->persist _INTE_PER_SEC);while (running){//P 操作cout << “消费者线程” << m_serial << “ 请求消费.” << endl;WaitForSingleObject(g_hFullSemaphore, INFINITE);cout << “消费者线程” << m_serial << “ 请求独占缓冲区.” << endl;WaitForSingleObject(g_hMute_,INFINITE);Sleep(m_delay); //延迟等待//从缓冲区中取出一个产品cout << “消费者线程” << m_serial << “ 请求取出一个产品.” << endl;ConsumeID = g_buffer[out];g_buffer[out] = 0;out = (out + 1) % SIZE_OF_BUFFER;cout << “消费者线程” << m_serial << “ 取出产品” << ConsumeID << “ 成功.” << endl;//消耗一个产品cout << “消费者线程” << m_serial << “ 开始消费消费产品” << ConsumeID << “.” << endl;Sleep(m_persist);cout << “消费者线程” << m_serial << “ 消费产品” << ConsumeID << “ 成功.” << endl;//输出缓冲区当前的状态cout << “____________________________” << endl<< “\n 当前缓冲区情况如图:” << endl;for (int i = 0;i < SIZE_OF_BUFFER;++i){if (g_buffer[i] != 0)cout << “■”;elsecout << “□”;}cout << “\n\n____________________________\n” << endl;//V 操作ReleaseMute_(g_hMute_);ReleaseSemaphore(g_hEmptySemaphore, 1, NULL);} }void prod_cons {//创建互斥信号量g_hMute_ = CreateMute_(NULL, FALSE, NULL);//创建同步信号量g_hEmptySemaphore = CreateSemaphore(NULL,SIZE_OF_BUFFER, SIZE_OF_BUFFER, NULL);g_hFullSemaphore = CreateSemaphore(NULL, 0,SIZE_OF_BUFFER, NULL);srand((unsigned)time(NULL));//以时间函数为种子const unsigned short THREADS_COUNT = rand % 5 + 5; //总的线程数(随机生成)//线程对象的数组HANDLE hThreads[MA__THREAD_NUM];ThreadInfo thread_info[MA__THREAD_NUM];DWORD thread_ID; //线程 IDint num = 0;//临时变量,用于循环语句cout << “系统开始模拟,并自动生成模拟数据...” << endl;system(“pause”); //暂停确认开始执行cout << “线程总数:” << THREADS_COUNT << endl;//循环随机生成各个线程的信息while (num != THREADS_COUNT){thread_info[num].serial = num + 1;if (rand % 2 == 1)thread_info[num].entity = "P";elsethread_info[num].entity = "C";thread_info[num].delay = rand % 5 + 1;thread_info[num].persist = rand % 6 + 2;num++;}cout << “\n 系统生成数据结束,模拟数据如下:” << endl<< “线程号线程类别延迟时间操作时间” << endl;for (int _ = 0;_ < THREADS_COUNT;_++)cout << “” << thread_info[_].serial << “\t”<< “” << thread_info[_].entity << “\t”<< “” << thread_info[_].delay << “\t\t”<< “” << thread_info[_].persist << endl;cout << “\n\n==================生产者-消费者开始==================\n” << endl;//创建线程for (int i = 0;i < THREADS_COUNT;i++){//创建生产者线程if (thread_info[i].entity == "P")hThreads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(Producer), ;thread_info[i], 0, ;thread_ID);//创建消费者线程elsehThreads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(Consumer), ;thread_info[i], 0, ;thread_ID);}while (running){if (getchar){//按回车后终止程序运行running = false;}}cout << “系统模拟结束...” << endl; } int main {cout << “\n==================生产者-消费者模拟==================\n” << endl;prod_cons; }五、实验过程1、记录生产者和消费者的同步执行过程。
线程实验报告

线程实验报告线程实验报告引言:线程是计算机科学中的一个重要概念,它是操作系统能够进行运算调度的最小单位。
线程的使用能够提高程序的并发性和响应性,使得程序能够更高效地利用计算机资源。
本次实验旨在通过编写一个简单的多线程程序,来探究线程的工作原理和应用。
实验目的:1. 了解线程的基本概念和特点;2. 掌握线程的创建、同步和销毁方法;3. 理解多线程编程的优势和挑战。
实验过程:1. 创建线程在实验开始时,我们首先需要创建线程。
在C++中,可以使用pthread库来实现。
通过调用pthread_create函数,我们可以创建一个新的线程,并将其与指定的函数进行绑定。
在实验中,我们创建了两个线程,分别执行不同的任务。
2. 线程同步在多线程编程中,线程之间的同步是一个重要的问题。
为了避免竞态条件和资源争用,我们需要使用互斥锁和条件变量等同步机制。
在本次实验中,我们使用了互斥锁来保护共享资源的访问,以及条件变量来实现线程之间的通信。
3. 线程销毁线程的销毁是一个关键的步骤。
在实验中,我们使用了pthread_join函数来等待线程的结束,并回收线程的资源。
这样可以确保线程的正确退出,避免资源泄漏和程序崩溃。
实验结果:通过实验,我们发现多线程编程具有以下优势:1. 提高程序的并发性:通过并行执行多个任务,可以提高程序的运行效率,减少等待时间。
2. 增强程序的响应性:多线程可以使程序具有更好的交互性,用户可以在任务执行的同时进行其他操作。
3. 充分利用计算机资源:多线程能够充分利用多核处理器的计算能力,提高系统的整体性能。
然而,多线程编程也存在一些挑战:1. 竞态条件:当多个线程同时访问共享资源时,可能会导致数据的不一致性和程序的错误。
2. 死锁和饥饿:线程之间的同步问题可能导致死锁和饥饿现象,使得程序无法正常执行。
3. 调试困难:多线程程序的调试比单线程程序更加困难,需要仔细分析线程之间的交互关系。
结论:通过本次实验,我们深入了解了线程的工作原理和应用。
多线程通信实验报告(3篇)

第1篇一、实验目的1. 理解多线程的概念和原理。
2. 掌握多线程间的通信方法,如共享内存、消息队列、信号量等。
3. 通过实验加深对多线程编程的理解,提高编程能力。
二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发工具:Visual Studio 2019三、实验内容1. 创建多线程2. 线程同步与互斥3. 线程间通信四、实验步骤1. 创建多线程(1)使用std::thread创建线程对象。
(2)在线程函数中定义线程要执行的任务。
(3)启动线程。
2. 线程同步与互斥(1)使用std::mutex互斥锁保护共享资源。
(2)使用std::lock_guard自动管理互斥锁。
(3)使用std::unique_lock手动管理互斥锁。
3. 线程间通信(1)使用共享内存a. 使用std::shared_mutex保护共享内存。
b. 使用std::lock_guard或std::unique_lock自动管理互斥锁。
c. 在线程函数中读取和写入共享内存。
(2)使用消息队列a. 使用std::queue创建消息队列。
b. 使用std::mutex保护消息队列。
c. 在生产者线程中添加消息到队列。
d. 在消费者线程中从队列中读取消息。
(3)使用信号量a. 使用std::semaphore创建信号量。
b. 在生产者线程中调用sem_post()增加信号量。
c. 在消费者线程中调用sem_wait()等待信号量。
五、实验代码```cppinclude <iostream>include <thread>include <mutex>include <queue>include <semaphore>std::mutex mtx;std::queue<int> q;std::semaphore sem(0);void producer() {for (int i = 0; i < 10; ++i) {std::this_thread::sleep_for(std::chrono::milliseconds(100)); std::lock_guard<std::mutex> lock(mtx);q.push(i);std::cout << "Produced: " << i << std::endl;sem.post();}}void consumer() {while (true) {sem.wait();std::lock_guard<std::mutex> lock(mtx);int value = q.front();q.pop();std::cout << "Consumed: " << value << std::endl;}}int main() {std::thread t1(producer);std::thread t2(consumer);t1.join();t2.join();return 0;}```六、实验结果与分析1. 创建多线程成功,线程函数执行任务。
多线程程序实验报告(3篇)

第1篇一、实验目的1. 理解多线程的概念和作用。
2. 掌握多线程的创建、同步和通信方法。
3. 熟悉Java中多线程的实现方式。
4. 提高程序设计能力和实际应用能力。
二、实验环境1. 操作系统:Windows 102. 开发工具:IntelliJ IDEA3. 编程语言:Java三、实验内容本次实验主要完成以下任务:1. 创建多线程程序,实现两个线程分别执行不同的任务。
2. 使用同步方法实现线程间的同步。
3. 使用线程通信机制实现线程间的协作。
四、实验步骤1. 创建两个线程类,分别为Thread1和Thread2。
```javapublic class Thread1 extends Thread {@Overridepublic void run() {// 执行Thread1的任务for (int i = 0; i < 10; i++) {System.out.println("Thread1: " + i);}}}public class Thread2 extends Thread {@Overridepublic void run() {// 执行Thread2的任务for (int i = 0; i < 10; i++) {System.out.println("Thread2: " + i);}}}```2. 创建一个主类,在主类中创建两个线程对象,并启动它们。
```javapublic class Main {public static void main(String[] args) {Thread thread1 = new Thread1();Thread thread2 = new Thread2();thread1.start();thread2.start();}```3. 使用同步方法实现线程间的同步。
```javapublic class SynchronizedThread extends Thread {private static int count = 0;@Overridepublic void run() {for (int i = 0; i < 10; i++) {synchronized (SynchronizedThread.class) {count++;System.out.println(Thread.currentThread().getName() + ": " + count);}}}}public class Main {public static void main(String[] args) {Thread thread1 = new SynchronizedThread();Thread thread2 = new SynchronizedThread();thread1.start();thread2.start();}```4. 使用线程通信机制实现线程间的协作。
线程实例实验报告总结

一、实验目的本次实验旨在通过实例操作,深入了解线程的概念、创建、同步与通信机制,以及线程在实际编程中的应用。
通过实验,提高对线程的理解和运用能力,为以后开发多线程程序打下坚实基础。
二、实验环境1. 操作系统:Windows 102. 开发工具:Visual Studio 20193. 编程语言:C#三、实验内容1. 线程的基本概念线程是程序执行的最小单位,是操作系统进行资源分配和调度的基本单位。
线程具有以下特点:(1)线程是轻量级的,创建、销毁线程的开销较小。
(2)线程共享进程的资源,如内存、文件等。
(3)线程之间可以并发执行。
2. 线程的创建在C#中,可以使用以下方式创建线程:(1)使用Thread类```csharpThread thread = new Thread(new ThreadStart(MethodName));thread.Start();```(2)使用lambda表达式```csharpThread thread = new Thread(() => MethodName());thread.Start();```(3)使用匿名方法```csharpThread thread = new Thread(delegate () { MethodName(); });thread.Start();```3. 线程的同步线程同步是指多个线程在执行过程中,为了防止资源冲突而采取的协调机制。
C#提供了以下同步机制:(1)互斥锁(Mutex)```csharpMutex mutex = new Mutex();mutex.WaitOne();// 线程同步代码mutex.ReleaseMutex();```(2)信号量(Semaphore)```csharpSemaphore semaphore = new Semaphore(1, 1);semaphore.WaitOne();// 线程同步代码semaphore.Release();```(3)读写锁(ReaderWriterLock)```csharpReaderWriterLock rwlock = new ReaderWriterLock();rwlock.AcquireReaderLock();// 读取操作rwlock.ReleaseReaderLock();```4. 线程的通信线程通信是指线程之间传递消息、共享数据的过程。
操作系统线程同步实验报告

线程同步实验报告
实验目的:讨论临界区问题及其解决方案。
实验内容:首先创建两个共享数据资源的并发进程,然后分别在没有同步控制机制、采用mutex机制以及使用软件方法(Peterson)的情况下探究并尽量解决所产生的异常情况。
实验结果:(一)结果截图
1、没有同步控制机制
2、使用mutex机制(其中run1、run2是标志进程输出次数)
3、Peterson算法
(二)结果分析
按照输出结果的稳定性来评判一个程序的好坏,那么大体可以总结为:没有使用同步控制机制<mutex机制<软件机制。
mutex机制是实现由一个进程对公共资源进行访问的时候,不允许其它进程对此资源进行访问。
保证了进程之间的互斥性。
软件机制是使用Peterson算法实现进程间的轮流进行以及进程之间的互斥性。
但是实验结果显示每一种方法均存在异常情况,即在一定次数后程序结束。
产生异常的原因大致分为以下几种:1、进程间的相互影响导致在访问同一个共同资源时会出现变量值与理论值产生偏差,使得不满足循环条件;2、针对单处理机的程序在处理多处理机的问题上会出现偏差;3、PC机本身内存可能存在的部分遗留的数据会影响数据的运算。
线程的互斥实验报告总结

线程的互斥实验报告总结
本次实验是关于线程互斥的,旨在通过使用互斥锁和信号量等机制,让学生能够更好地理解并掌握线程的互斥操作。
在本次实验中,我们首先学习了互斥锁的概念和使用方法。
互斥
锁是一种最常用的线程同步机制,用来保证多个线程之间的互斥操作。
通过使用互斥锁,我们可以避免两个或多个线程同时访问共享资源而
导致数据异常的问题。
实验中,我们对比了有互斥锁与没有互斥锁对
共享变量的访问结果,明显地看到了在没有互斥锁的情况下,数据会
发生异常。
除了互斥锁,我们还学习了信号量的概念和使用方法。
信号量是
一种用于控制访问共享资源的标志,在多线程程序中广泛应用。
使用
信号量可以保证多个线程间共享资源的安全性,并可以避免资源竞争
和死锁的发生。
在实验中,我们还利用信号量实现了线程的同步和互
斥操作。
通过本次实验,我深感互斥锁和信号量在多线程程序中的重要性。
在多线程编程中,不仅要考虑到线程之间的并发问题,也需要关注到
线程之间的同步和互斥操作。
只有将线程同步和互斥机制运用到多线
程编程中,才能真正保证多线程程序的安全性和正确性。
综上所述,本次实验对于我来说是非常有意义的。
通过学习互斥
锁和信号量等线程同步机制,我对于多线程编程的思想和技术又有了
更深刻的理解和认识。
我相信,在今后的学习和工作中,所学到的知识一定会给我带来更多的帮助和启示。
实验五 多线程程序设计 实验报告

实验五多线程程序设计实验报告一、实验目的1. 熟悉利用Thread 类建立多线程的方法。
2. 熟悉利用Runnable 接口建立多线程的方法。
二、实验原理1. 通过继承Thread 类实现多线程的方法:① 创建一个Thread 类的子类。
② 重写run 方法。
③ 创建这个子类的实例。
④调用子类的start 方法启动线程。
2. 通过Runnable 接口实现多线程的方法:① 创建一个线程类,实现Runnable 接口。
② 实现run 方法。
③ 通过Thread 类中的Thread(Runnable) 构造方法创建一个线程类实例。
④ 调用线程类的start 方法启动线程。
三、实验内容1. 阅读下列程序,分析并上机检验其功能。
class DelayThread extends Thread {private static int count=0;private int no;private int delay;public DelayThread() {count++;no=count;}public void run() {try {for (int i=0;i<10;i++){delay=(int)(Math.random()*5000);sleep(delay);System.out.println(“Thread ”+no+” with a delay ”+delay);} catch(InterruptedException e) { }}}public class MyThread {public static void main(String args[]) {DelayThread thread1 = new DelayThread();DelayThread thread2 = new DelayThread();thread1.start();thread2.start();try {Thread.sleep(1000);} catch (InterruptedException e) {System.out.println(“Thread wrong”);}}}2. 利用Runnable 接口修改上面的程序,使之完成同样的功能。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
线程实验报告黄澄宇3200709112411.分析(1)问题阐述,描述。
运用线程的方法设计一个ftp面向客户\服务器的网络应用程序,主要包括服务器端和客户端两方面的工作。
(2)问题分析。
针对问题要求,应该能够实现客户端和服务器端的功能。
其中服务器端主要对客户端进行监听。
客户端向服务器端进行提出请求。
(3)寻找揭发。
TCP\IP服务器端应用程序都是通过JA V A语言中提供的SeverSocket和Socket两个有关网络的类来实现。
SeverSocket类除了建立一个Sever之外,还通过accept()方法提供了随时监听客户端连接请求的功能。
2.设计。
在服务器端指定一个用来等待连接的端口号,在客户端规定一个主机和端口号,从而在客户端和服务器端创建Socket\ServerSocket实例。
现在服务器端生成一个ServerSocket实例的对象,随时监听客户端的连接请求。
当客户端需要连接时,相应的要生成一个Socket实例的对象,并发出连接请求,其在host参数指明该主机名,port参数指明端口号。
服务器端通过accept()方法接收到客户端的请求后,开辟一个接口与之进行连接,利用输入输出流,按照一定的协议对Socket 进行读写操作。
关闭输入输出流和Socket。
3.实现。
//FTPServer.javaimport .*;import java.io.*;import java.util.*;public class FTPServer{public static void main(String args[]) throws Exception{ServerSocket soc=new ServerSocket(5127);System.out.println("FTP Server Started on Port Number ");while(true){System.out.println("Waiting for Connection..."); transferfile t=new transferfile(soc.accept());}}}class transferfile extends Thread{Socket ClientSoc;DataInputStream din;DataOutputStream dout;transferfile(Socket soc){try{ClientSoc=soc;din=new DataInputStream(ClientSoc.getInputStream()); dout=new DataOutputStream(ClientSoc.getOutputStream()); System.out.println("FTP Client Connected...");start();}catch(Exception ex){}}void SendFile() throws Exception{String filename=din.readUTF();File f=new File(filename);if(!f.exists()){dout.writeUTF("File Not Found"); return;}else{dout.writeUTF("READY"); FileInputStream fin=new FileInputStream(f); int ch;do{ch=fin.read();dout.writeUTF(String.valueOf(ch));}while(ch!=-1);fin.close();dout.writeUTF("File Receive Successfully"); }}void ReceiveFile() throws Exception{String filename=din.readUTF();if(pareTo("File not found")==0) {return;}File f=new File(filename);String option;if(f.exists()){dout.writeUTF("File Already Exists"); option=din.readUTF();}else{dout.writeUTF("SendFile");option="Y";if(pareTo("Y")==0){FileOutputStream fout=new FileOutputStream(f); int ch;String temp;do{temp=din.readUTF();ch=Integer.parseInt(temp);if(ch!=-1){fout.write(ch);}}while(ch!=-1);fout.close();dout.writeUTF("File Send Successfully");}else{return;}public void run(){while(true){try{System.out.println("Waiting for Command..."); String Command=din.readUTF();if(pareTo("GET")==0){System.out.println("\tGET Command Received..."); SendFile();continue;}else if(pareTo("SEND")==0){System.out.println("\tSEND Command Receiced "); ReceiveFile();continue;}else if(pareTo("DISCONNECT")==0)System.out.println("\tDisconnect Command Received "); System.exit(1);}}catch(Exception ex){}}}}/FTPClient.javaimport .*;import java.io.*;import java.util.*;class FTPClient{public static void main(String args[]) throws Exception {Socket soc=new Socket("127.0.0.1",5127); transferfileClient t=new transferfileClient(soc);t.displayMenu();}class transferfileClient{Socket ClientSoc;DataInputStream din;DataOutputStream dout;BufferedReader br;transferfileClient(Socket soc){try{ClientSoc=soc;din=new DataInputStream(ClientSoc.getInputStream()); dout=new DataOutputStream(ClientSoc.getOutputStream()); br=new BufferedReader(new InputStreamReader(System.in)); }catch(Exception ex){}}void SendFile() throws ExceptionString filename;System.out.print("Enter File Name :");filename=br.readLine();File f=new File(filename);if(!f.exists()){System.out.println("File not Exists");dout.writeUTF("File not found");return;}dout.writeUTF(filename);String msgFromServer=din.readUTF();if(pareTo("File Already Exists")==0){String Option;System.out.println("File Already Exists Want to OverWrite (Y/N) ?"); Option=br.readLine();if(Option=="Y"){dout.writeUTF("Y");}else{dout.writeUTF("N");return;}}System.out.println("Sending File..."); FileInputStream fin=new FileInputStream(f); int ch;do{ch=fin.read();dout.writeUTF(String.valueOf(ch));}while(ch!=-1);fin.close();System.out.println(din.readUTF());}void ReceiveFile() throws Exception{String fileName;System.out.print("Enter File Name :"); fileName=br.readLine();dout.writeUTF(fileName);String msgFromServer=din.readUTF();if(pareTo("File Not Found")==0){System.out.println("File not found on Server...");return;}else if(pareTo("READY")==0){System.out.println("Receiving File... ");File f=new File(fileName);if(f.exists()){String Option;System.out.println("File Already Exists. Want to OverWrite (Y/N) ?"); Option=br.readLine();if(Option=="N"){dout.flush();return;}}FileOutputStream fout=new FileOutputStream(f); int ch;String temp;do{temp=din.readUTF();ch=Integer.parseInt(temp);if(ch!=-1){fout.write(ch);}}while(ch!=-1);fout.close();System.out.println(din.readUTF());}}public void displayMenu() throws Exception {while(true){System.out.println("[ MENU ]");System.out.println("1.Send File");System.out.println("2.Receive File"); System.out.println("3.Exit"); System.out.print("\nEnter Choice :"); int choice;choice=Integer.parseInt(br.readLine()); if(choice==1){dout.writeUTF("SEND");SendFile();}else if(choice==2){dout.writeUTF("GET"); ReceiveFile();}else{dout.writeUTF("DISCONNECT"); System.exit(1);}}}}。