Khoa Khoa học & Kỹ thuật Máy tính, trường Đại Học Bách Khoa – ĐHQG Tp.HCM
BÀI THỰC HÀNH SỐ 11
-
Mục tiêu
-
Xây dựng ứng dụng gởi nhận file.đơn giản.
-
Các bước thực hiện
-
Xây dựng giao thức đơn giản
-
Lệnh Upload: PUT FILENAME
-
Lệnh Download: GET FILENAME NEW_FILENAME
-
Lệnh thoát: QUIT
-
Giá trị trả về:
-
Thực thi lệnh thành công : 200 OK
-
Không tìm thấy tập tin để download : 201 File Not Found
-
Tập tin đã tồn tại khi upload : 202 File Existed
-
Các lệnh chưa hỗ trợ : 203 Bad Request
-
Soạn thảo tập tin FileServer.java (Lưu ý: hiệu chỉnh các đoạn …)
import java.net.*;
import java.io.*;
import java.util.*;
public class FileServer {
public static void main (String argv[]) throws IOException {
int port = 8000; // server port number
// Create a ServerSocket object
ServerSocket server_socket = ...
System.out.println ("Server started");
// Loop indefinitely while waiting for clients to connect
while (true) {
// accept () does not return until a client requests a connection
Socket client_socket = ...
// Now that a client has arrived, create an instance of our special
// thread subclass to respond to it.
Worker worker = new Worker (client_socket);
...
System.out.println ("New client connected");
}
} // main
} // class FileServer
-
Soạn thảo tập tin Worker.java (Lưu ý: hiệu chỉnh các đoạn …)
import java.net.*;
import java.io.*;
import java.util.*;
/** Threaded process to serve the client connected to the socket.**/
class Worker extends Thread {
Socket socket = null;
/** Pass the socket as a argument to the constructor **/
Worker ( Socket client_socket ) throws SocketException {
socket = client_socket;
// Set the thread priority down so that the ServerSocket
// will be responsive to new clients.
setPriority ( NORM_PRIORITY - 1 );
}
/**
* This thread receives a message from the client that will
* request a web page file. The file name is found relative to
* the directory location of this code.
**/
public void run () {
try {
// Use the client socket to obtain an input stream from it.
InputStream is = ...
// For text input we wrap an InputStreamReader around
// the raw input stream and set ASCII character encoding.
InputStreamReader isr =
new InputStreamReader (is, "8859_1");
// Finally, use a BufferReader wrapper to obtain
// buffering and higher order read methods.
BufferedReader in = new BufferedReader (isr);
// Now get an output stream to the client.
OutputStream os = ...
// For text output we wrap an OutputStreamWriter around
// the raw output stream and set ASCII character encoding.
OutputStreamWriter osr =
new OutputStreamWriter (os, "8859_1");
// Finally, we use a PrintWriter wrapper to obtain its
// higher level output methods.Open in autoflush mode.
// (Autoflush occurs only with println() method.)
PrintWriter out = new PrintWriter (osr, true);
while (true)
{
// First read the message from the client
String str = in.readLine ();
System.out.println ("Client message: " + str);
// Example: GET example.txt
// Split the message into substrings.
String [] tokens = str.split(" ");
if ((tokens.length >= 1) &&
tokens[0].equals ("QUIT")) {
...
}
// Check that the message has a minimun number of words
// and that the first word is the GET command.
if ((tokens.length >= 2) &&
tokens[0].equals ("GET")) {
String file_name = tokens[1];
// Now read the file from the disk and write it to the
// output stream to the client.
try {
// Open a stream to the file.
FileInputStream file_in = new FileInputStream (file_name);
// Send the header.
out.println("200 OK\r\n");
File file = new File (file_name);
out.println("Content-length: " + file_in.available ()
+ "\r\n");
// Creat a byte array to hold the file.
byte [] data = new byte [file_in.available ()];
file_in.read (data); // Read file into the byte array
os.write (data); // Write it to client output stream
os.flush (); // Remember to flush output buffer
file_in.close (); // Close file input stream
} catch (FileNotFoundException e) {
// If no such file, then send the 201 message.
out.println ("201 File Not Found" );
}
//}
// Check that the message has a minimun number of words
// and that the first word is the GET command.
//else if ((tokens.length >= 2) &&
// tokens[0].equals ("PUT")) {
//String file_name = tokens[1];
// Now read the input stream from client and write it to the disk.
//try {
// Open a stream to the file.
//FileOutStream file_out = new FileOutputStream (file_name);
//...
//} catch (FileNotFoundException e) {
// out.println ("202 File Existed" );
//}
} else {
out.println ("203 Bad Request");
}
} catch (FileNotFoundException e) {
out.println ("202 File Existed");
}
catch (IOException e) {
System.out.println ( "I/O error " + e );
}
} // End while
// Close client socket.
try {
...
} catch (IOException e){
System.out.println ("I/O error " + e );
}
// On return from run () the thread process will stop.
} // run
} // class Worker
-
Thực thi FileServer
-
Copy tập tin example.txt tại thư mục chứa 2 tập tin Java nói trên (ví dụ c:\bai2)
-
Biên dịch và thực thi File Server:
C:\bai2> javac Worker.java FileServer.java
C:\bai1> java FileServer
telnet 127.0.0.1 8000
GET example.txt
-
Quan sát kết quả trên Command Prompt.
-
Soạn thảo tập tin FileClient.java (Lưu ý: hiệu chỉnh các đoạn …)
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
/**
* This program provides a graphical user interface to
* set up the connection to a server and to download/upload
* the file from/to the server.
**/
public class ClientClient extends JFrame
implements Runnable, ActionListener
{
//
JTextArea fTextArea = null;
JTextField fIpField;
JTextField fPortField;
JTextField fFileField;
// Default address is local
String fIpAddr = "127.0.0.1";
// Default port
int fPort = 8000;
// Socket to connect with server.
Socket fSocket = null;
// File name
String fFilename = "example.txt";
// Change the button name as needed
String fButtonName = "Get";
JButton fButton = null;
Thread fThread = null;
/** Start the program. **/
public static void main (String [] args) {
FileClient f =
new FileClient ("Client for FileServer ");
f.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
/**
* Create user interface for client. Includes text fields
* for the server IP address, the server's port number, a
* text area to show the data returned from the server, and
* a button to initiate the connection to the server.
**/
FileClient (String title){
super (title);
Container content_pane = getContentPane ();
// Create a user interface.
content_pane.setLayout ( new BorderLayout () );
fTextArea = new JTextArea ("");
fTextArea.setLineWrap (true);
content_pane.add ( fTextArea, "Center");
// Create a panel with three text fields to obtain
// the server address, the port number,
// the file to download, and to initiate the link
// with the server.
fIpField = new JTextField (fIpAddr);
fPortField = new JTextField (""+fPort);
fFileField= new JTextField (fFilename);
// Button to initiate the download from the server
fButton = new JButton (fButtonName);
fButton.addActionListener (this);
JPanel panel = new JPanel (new GridLayout (2,2));
panel.add (fIpField);
panel.add (fPortField);
panel.add (fFileField);
panel.add (fButton);
content_pane.add ( panel, "South");
setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
}
/** Process events from the frame menu and the chooser.**/
public void actionPerformed ( ActionEvent e ){
boolean status = false;
String command = e.getActionCommand ();
if (command.equals (fButtonName) ) {
// First get the server address
fIpAddr = fIpField.getText ();
// Get port number
fPort = Integer.parseInt (fPortField.getText ());
// Get the name of the file to download
fFilename = fFileField.getText ();
start ();
}
}
/**
* Start the thread to connect to the server
* and read the file from it.
*/
public void start (){
// If the thread reference not null then a
// thread is already running. Otherwise, create
// a thread and start it.
if (fThread == null) {
fThread = new Thread (this);
fThread.start ();
}
} // start
/** Connect with the server via a thread process. **/
public void run () {
// Clear the text area
fTextArea.setText ("Downloading...");
try{
// Connect to the server via the given IP address and port number
...
// Assemble the message line.
String message = "GET " + fFilename;
// Now get an output stream to the server.
OutputStream os = ...
// Wrap in writer classes
PrintWriter pw = new PrintWriter (
new OutputStreamWriter (os, "8859_1"), true );
// Send the message to the server
pw.println (message);
// Get the input stream from the server and then
// wrap the stream in two wrappers.
BufferedReader br = new BufferedReader (
new InputStreamReader ( ... ) );
String line;
// Get some first line to get file size
...
// Prepare buffer to get data from File Server and save to local file
...
fTextArea.setText ("OK");
// Send message QUIT to the server
pw.println (“QUIT”);
} catch ( UnknownHostException uhe) {
fTextArea.setText ("Unknown host");
} catch ( IOException ioe){
fTextArea.setText ("I/O Exception");
} finally{
try{
// End the connection
...
fThread=null;
} catch ( IOException ioe) {
fTextArea.append ("IO Exception while closing socket");
}
}
} // run
-
Thực thi FileClient
C:\bai1> javac FileClient.java
C:\bai1> java FileClient
-
Bài tập
-
Hoàn chỉnh phần hỗ trợ lệnh PUT của FileServer.java (Lưu ý các dòng comment // khi lệnh gởi đến là PUT.
-
Hiệu chỉnh FileClient.java hỗ trợ lệnh PUT.
-
Mở rộng giao thức với các lệnh DIR, CD
-
Mở rộng FileServer.java để hỗ trợ các lệnh DIR và CD
Về việc nộp bài thực hành:
-
Bài làm gồm các tập tin .java, .class, … được đặt vào một thư mục và nén thành 1 tập tin .zip cùng có tên là MSSV_Hovaten (ví dụ: 505032411_NguyenVanA.zip)
Trang /
Chia sẻ với bạn bè của bạn: |