-
10.2.4.3 ตัวอย่างที่ 3: การพัฒนาโปรโตคอลชั้นแอปพลิเคชันเครือข่าย
สำนักพิมพ์มหาวิทยาลัยซิงหัว "โปรแกรมเมอร์ Java, สิ่งที่ต้องทำในที่ทำงาน" ผู้เขียน: Zhong Sheng - ข้อความที่ตัดตอนบางส่วนจากบทที่ 10 "ปรมาจารย์มีพรสวรรค์เท่าที่เขาสามารถทำได้"
ทุกคนอาจเคยใช้เครื่องมืออัพโหลดและดาวน์โหลด FTP มาก่อน ตัวอย่างเช่น "LeapFTP" เป็นเครื่องมืออัพโหลดและดาวน์โหลดเซิร์ฟเวอร์ FTP ที่สะดวกมากดังแสดงในรูป เครื่องมือนี้สะดวกมาก หลังจากป้อนชื่อผู้ใช้และรหัสผ่านแล้ว คุณสามารถดูรายการไฟล์บนเซิร์ฟเวอร์ FTP ซึ่งอำนวยความสะดวกในการอัพโหลดและดาวน์โหลด
คุณเคยลองเขียนแอปพลิเคชันอัพโหลดไฟล์ FTP และดาวน์โหลดใน Java หรือไม่?
Java ยังสามารถพัฒนาโปรแกรมดังกล่าวได้ อันดับแรกเรามาดูวิธีการพัฒนาแอปพลิเคชัน FTP โดยใช้ชุดเครื่องมือ FTP ของ Java กันก่อน
นำเข้า sun.net.*;
นำเข้า sun.net.ftp.*;
FTP ระดับสาธารณะ {
โมฆะคงที่สาธารณะ main (String [] args) {
String server="192.168.0.12"; //ป้อนที่อยู่ IP ของเซิร์ฟเวอร์ FTP
String user="useway"; //ชื่อผู้ใช้เพื่อเข้าสู่เซิร์ฟเวอร์ FTP
String pass=" !@#$%abce "; // รหัสผ่านของชื่อผู้ใช้เพื่อเข้าสู่เซิร์ฟเวอร์ FTP
String path="/home/useway"; //เส้นทางบนเซิร์ฟเวอร์ FTP
พยายาม {
FtpClient ftpClient=new FtpClient(); //สร้างวัตถุ FtpClient
ftpClient.openServer(เซิร์ฟเวอร์); //เชื่อมต่อกับเซิร์ฟเวอร์ FTP
ftpClient.login(ผู้ใช้, รหัสผ่าน); //เข้าสู่ระบบเซิร์ฟเวอร์ FTP
ถ้า (path.length()!=0) ftpClient.cd(path);
TelnetInputStream คือ=ftpClient.list();
อินท์ค;
ในขณะที่ ((c=is.read())!=-1) {
System.out.print((ถ่าน)c);
-
คือ.ปิด();
ftpClient.closeServer();//ออกจากเซิร์ฟเวอร์ FTP
-
catch (ข้อยกเว้นเช่น) {
-
-
-
หากคุณสนใจคุณสามารถเขียนโปรแกรมนี้ได้ด้วยตัวเอง เมื่อรันโปรแกรมนี้ เราจะเห็นสถานการณ์ดังรูป โดยแสดงรายการเนื้อหาไดเร็กทอรีของโปรแกรมฝั่งเซิร์ฟเวอร์
โปรแกรมนี้เป็นโปรแกรมง่ายๆ เพื่อรับรายการไฟล์บนเซิร์ฟเวอร์ FTP แต่อย่าเข้าใจผิด โปรแกรมนี้ไม่สามารถเรียกได้ว่าเป็นการพัฒนาโปรแกรม "Network Application Layer Protocol"!
โปรแกรมนี้ใช้เฉพาะคลาสที่เกี่ยวข้องใน "sun.net.*;" และ "sun.net.ftp.*;" เพื่อใช้งานฝั่ง FTP คำขอถูกส่งไปยังไคลเอ็นต์ แต่คำขอลิงก์จะถูกส่งไปยังเซิร์ฟเวอร์ผ่านชุดเครื่องมือที่ Java จัดเตรียมไว้ให้
ข้อดีของการใช้แพ็คเกจ FTP ของ Java เพื่อเชื่อมต่อกับเซิร์ฟเวอร์ FTP คือเราไม่จำเป็นต้องสนใจรายละเอียดเฉพาะของการส่งข้อมูลในระดับเครือข่าย แต่ต้องเรียกวิธีการที่เกี่ยวข้องเท่านั้น ข้อเสียของการใช้แพ็คเกจ FTP ของ Java เพื่อเชื่อมต่อกับเซิร์ฟเวอร์ FTP คือนักพัฒนาไม่ทราบรายละเอียดของการส่งและรับโปรโตคอลเลเยอร์แอปพลิเคชัน ไม่สามารถเข้าใจหลักการ และเข้าใจข้อมูลพื้นฐานได้น้อยมาก
ณ จุดนี้ โปรแกรมเมอร์บางคนจะถามว่า: "แล้ว FTP โต้ตอบระหว่างพีซีและเซิร์ฟเวอร์ในระดับเครือข่ายอย่างไร" ให้ฉันแสดงรายการกระบวนการโต้ตอบของโปรโตคอล FTP ให้คุณ
โปรดดูตัวอย่างการโต้ตอบโปรโตคอล FTP ต่อไปนี้:
เซิร์ฟเวอร์ FTP: 220 (เทียบกับ FTPd 2.0.1)
ไคลเอ็นต์ FTP: ช่องทางการใช้งานของ USER
เซิร์ฟเวอร์ FTP: 331 โปรดระบุรหัสผ่าน
ไคลเอ็นต์ FTP: PASS !@#$%abce
เซิร์ฟเวอร์ FTP: 230 เข้าสู่ระบบสำเร็จ
ไคลเอ็นต์ FTP: CWD /home/useway
เซิร์ฟเวอร์ FTP: เปลี่ยนไดเรกทอรี 250 สำเร็จแล้ว
ไคลเอ็นต์ FTP: EPSV ทั้งหมด
เซิร์ฟเวอร์ FTP: 200 EPSV ทั้งหมดตกลง
ไคลเอ็นต์ FTP: EPSV
เซิร์ฟเวอร์ FTP: 229 เข้าสู่โหมด Extended Passive (|||62501|)
ไคลเอ็นต์ FTP: LIST
เซิร์ฟเวอร์ FTP: 150 นี่คือรายการไดเร็กทอรี
เซิร์ฟเวอร์ FTP: 226 ไดเรกทอรีส่งตกลง
ไคลเอ็นต์ FTP: QUIT
เซิร์ฟเวอร์ FTP: 221 ลาก่อน
ข้อความข้างต้นเป็นกระบวนการโต้ตอบระหว่างเซิร์ฟเวอร์ FTP และไคลเอนต์ FTP โปรโตคอลสำหรับการส่งข้อมูลระหว่างกันคือโปรโตคอล TCP และเนื้อหาที่ส่งถึงกันคือสิ่งที่เขียนไว้ในข้อความด้านบน
มาอธิบายความหมายของแต่ละประโยคทีละขั้นตอน:
เซิร์ฟเวอร์ FTP: 220 (vsFTPd 2.0.1) | คำอธิบาย: ลิงก์สำเร็จ
ไคลเอ็นต์ FTP: USER useway |คำแนะนำ: ป้อนชื่อผู้ใช้
เซิร์ฟเวอร์ FTP: 331 โปรดระบุรหัสผ่าน | คำอธิบาย: โปรดป้อนรหัสผ่าน
ไคลเอ็นต์ FTP: PASS !@#$%abce |คำแนะนำ: ป้อนรหัสผ่าน
เซิร์ฟเวอร์ FTP: 230 เข้าสู่ระบบสำเร็จ |.
ไคลเอ็นต์ FTP: CWD /home/useway | คำอธิบาย: สลับไดเรกทอรี
เซิร์ฟเวอร์ FTP: เปลี่ยนไดเร็กทอรี 250 สำเร็จแล้ว | คำอธิบาย: เปลี่ยนไดเร็กทอรีสำเร็จ
ไคลเอ็นต์ FTP: EPSV ALL | . คำอธิบาย: โหมดลิงก์แบบพาสซีฟ EPSV
เซิร์ฟเวอร์ FTP: 200 EPSV ทั้งหมดตกลง
ไคลเอนต์ FTP: EPSV | . คำอธิบาย: ลิงก์
เซิร์ฟเวอร์ FTP: 229 เข้าสู่โหมด Extended Passive (|||62501|) | คำอธิบาย: พอร์ตลิงก์แบบพาสซีฟคือ 62501
ไคลเอนต์ FTP: LIST | . คำอธิบาย: ดำเนินการ LIST เพื่อแสดงรายการไฟล์
เซิร์ฟเวอร์ FTP: 150 นี่คือรายการไดเร็กทอรี | คำอธิบาย: รายการถูกส่งจากพอร์ต 62501
เซิร์ฟเวอร์ FTP: 226 ไดเรกทอรีส่งตกลง | คำอธิบาย: ส่งเสร็จสมบูรณ์
ไคลเอนต์ FTP: QUIT | . คำอธิบาย: ออกจาก FTP
เซิร์ฟเวอร์ FTP: 221 ลาก่อน |
ด้วยเนื้อหาของข้อความข้างต้น เราสามารถรับรายการไฟล์ FTP โดยไม่ต้องใช้เครื่องมือใดๆ หากคุณไม่เชื่อ ให้ทำตามฉันแล้วทำใหม่อีกครั้ง
ขั้นตอนที่ 1: ขั้นแรกให้เปิด CMD เพื่อเข้าสู่โหมดบรรทัดคำสั่ง DOS และพิมพ์:
เทลเน็ต 192.168.0.1 21[เข้า]
คำอธิบาย: Telnet ไปยังพอร์ต 21 ของเซิร์ฟเวอร์ Ftp
หลังจากดำเนินการคำสั่งนี้แล้วผลลัพธ์ที่ได้จะเป็นดังแสดงในรูป
คุณพบปัญหาหรือไม่?
เนื้อหาของพรอมต์คือประโยคแรกของย่อหน้าด้านบน: 220 (vsFTPd 2.0.1) ซึ่งหมายความว่าเซิร์ฟเวอร์ FTP ยอมรับลิงก์ของเราแล้วและสามารถดำเนินการขั้นตอนต่อไปได้
ขั้นตอนที่ 2: พิมพ์ชุดการส่งเนื้อหาต่อไปนี้ทีละรายการ:
การใช้งาน USER[Enter]
ผ่าน !@#$%abce [เข้า]
CWD /home/useway[ป้อน]
EPSV ทั้งหมด[เข้า]
EPSV[ตกลง]
ผลลัพธ์ที่ได้จะแสดงในรูป
คราวนี้เซิร์ฟเวอร์ FTP ให้การตอบกลับหลายครั้ง และในที่สุดก็ให้หมายเลขพอร์ตใหม่ "58143"
ขั้นตอนที่ 3: เปิดหน้าต่าง CMD ใหม่และพิมพ์:
เทลเน็ต 192.168.0.1 58143[ป้อน]
โปรดทราบว่าหมายเลขพอร์ตของคำขอ Telnet เพื่อเชื่อมต่อกับเซิร์ฟเวอร์ในครั้งนี้คือ "58143" ซึ่งเป็นพอร์ตลิงก์ที่เซิร์ฟเวอร์ FTP มอบให้เรา หลังจากเชื่อมโยงแล้ว หน้าต่างจะว่างเปล่าโดยไม่มีการแจ้งใดๆ ดังแสดงในรูป
ขั้นตอนที่ 4: กลับไปที่หน้าต่าง CMD แรกแล้วพิมพ์:
รายการ[ป้อน]
ขั้นตอนที่ 5: ในขณะนี้ หน้าต่าง CMD ที่สองจะได้รับรายการไฟล์:
หน้าต่างที่สองจะได้รับรายชื่อไฟล์ดังแสดงในรูป
ขั้นตอนที่ 6: ออกจากการดำเนินการ
ออกจาก[ป้อน]
หลังจากดำเนินการเสร็จสิ้น ลิงก์ไปยังโฮสต์จะหายไป ดังแสดงในรูป
อย่างที่คุณเห็น โปรโตคอล FTP เป็นกระบวนการโต้ตอบ คุณยังสามารถดำเนินการคำสั่งพื้นฐานของ FTP ได้โดยใช้เครื่องมือ Telnet ที่มาพร้อมกับระบบ หากคุณต้องการใช้ Java's Socket เพื่อดำเนินการข้างต้นให้เสร็จสิ้น คุณจะต้องปฏิบัติตามเนื้อหาข้างต้นทีละขั้นตอนเพื่อส่งสตริงไปยังเซิร์ฟเวอร์ FTP
นอกจากนี้เรายังให้โค้ดตัวอย่างด้านล่าง:
นำเข้า java.io.InputStream;
นำเข้า java.io.OutputStream;
นำเข้า java.net.Socket;
FTPClient คลาสสาธารณะ{
โมฆะคงที่สาธารณะ main (String [] args) พ่นข้อยกเว้น {
ซ็อกเก็ต ซ็อกเก็ต = ซ็อกเก็ตใหม่ ("192.168.0.1",21);
InputStream คือ = socket.getInputStream();
OutputStream ระบบปฏิบัติการ = socket.getOutputStream();
//รับข้อมูลลิงค์เริ่มต้น
ไบต์ [] บัฟเฟอร์ = ไบต์ใหม่ [100];
int length = is.read (บัฟเฟอร์);
String s = new String (บัฟเฟอร์, 0, ความยาว);
System.out.println(s);
//ส่งชื่อผู้ใช้
String str = "USER usewayn";
os.write(str.getBytes());
//รับค่าที่ส่งคืน
length = is.read (บัฟเฟอร์);
s = สตริงใหม่ (บัฟเฟอร์, 0, ความยาว);
System.out.println(s);
//ส่งรหัสผ่าน
str = "ผ่าน !@#$%abcdn ";
os.write(str.getBytes());
//รับค่าที่ส่งคืน
length = is.read (บัฟเฟอร์);
s = สตริงใหม่ (บัฟเฟอร์, 0, ความยาว);
System.out.println(s);
//ส่งคำสั่งสลับโฟลเดอร์
str = "CWD /home/usewayn";
os.write(str.getBytes());
//รับค่าที่ส่งคืน
length = is.read (บัฟเฟอร์);
s = สตริงใหม่ (บัฟเฟอร์, 0, ความยาว);
System.out.println(s);
//ตั้งค่าโหมด
str = "EPSV ทั้งหมดn";
os.write(str.getBytes());
//รับค่าที่ส่งคืน
length = is.read (บัฟเฟอร์);
s = สตริงใหม่ (บัฟเฟอร์, 0, ความยาว);
System.out.println(s);
// รับข้อมูลการตรวจสอบแบบพาสซีฟ
str = "EPSVn";
os.write(str.getBytes());
//รับค่าที่ส่งคืน
length = is.read (บัฟเฟอร์);
s = สตริงใหม่ (บัฟเฟอร์, 0, ความยาว);
System.out.println(s);
// รับหมายเลขพอร์ตสำหรับการตรวจสอบแบบพาสซีฟ FTP
String portlist=s.substring(s.indexOf("(|||")+4,s.indexOf("|)"));
System.out.println (รายการพอร์ต);
//สร้างอินสแตนซ์คลาสเธรด ShowList และเชื่อมโยงหมายเลขพอร์ตการฟังแบบพาสซีฟของ FTP
ShowList sl=รายการโชว์ใหม่();
sl.port=Integer.parseInt(รายการพอร์ต);
sl.เริ่มต้น();
//ดำเนินการคำสั่ง LIST
str = "รายการn";
os.write(str.getBytes());
//รับค่าที่ส่งคืน
length = is.read (บัฟเฟอร์);
s = สตริงใหม่ (บัฟเฟอร์, 0, ความยาว);
System.out.println(s);
//ปิดลิงค์
คือ.ปิด();
os.ปิด();
ซ็อกเก็ต.ปิด();
-
-
//รับคลาสข้อมูลลิงก์แบบพาสซีฟ คลาสนี้เป็นแบบมัลติเธรด
คลาส ShowList ขยายเธรด {
พอร์ต int สาธารณะ = 0;
โมฆะสาธารณะวิ่ง () {
พยายาม{
ซ็อกเก็ต ซ็อกเก็ต = ซ็อกเก็ตใหม่ ("192.168.0.1",this.port);
InputStream คือ = socket.getInputStream();
OutputStream ระบบปฏิบัติการ = socket.getOutputStream();
ไบต์ [] บัฟเฟอร์ = ไบต์ใหม่ [10,000];
int length = is.read (บัฟเฟอร์);
String s = new String (บัฟเฟอร์, 0, ความยาว);
System.out.println(s);
//ปิดลิงค์
คือ.ปิด();
os.ปิด();
ซ็อกเก็ต.ปิด();
-
catch (ข้อยกเว้นเช่น) {
-
-
-
ผลลัพธ์การรันที่ได้รับหลังจากการรันโปรแกรมเป็นไปตามที่แสดงไว้ในภาพ โดยพื้นฐานแล้วมันจะเหมือนกับเอฟเฟกต์การรันด้านบน แล้วมันจะไม่มีอะไรมากไปกว่าการแกะวิธีการห่อหุ้มออกและรันมัน กฎการดำเนินงานเราก็ทำได้ โปรแกรมเดียวกันก็สามารถพัฒนาได้