วิธีสร้างแอปพลิเคชันเครือข่ายใน Java (พร้อมรูปภาพ)

สารบัญ:

วิธีสร้างแอปพลิเคชันเครือข่ายใน Java (พร้อมรูปภาพ)
วิธีสร้างแอปพลิเคชันเครือข่ายใน Java (พร้อมรูปภาพ)

วีดีโอ: วิธีสร้างแอปพลิเคชันเครือข่ายใน Java (พร้อมรูปภาพ)

วีดีโอ: วิธีสร้างแอปพลิเคชันเครือข่ายใน Java (พร้อมรูปภาพ)
วีดีโอ: สอนบันทึกหน้าจอ อัดวิดิโอหน้าจอ ใช้ได้กับมือถือทุกรุ่น ทุกยี่ห้อ 2024, อาจ
Anonim

การเขียนโค้ดที่รันบนอุปกรณ์บางเครื่องนั้นน่าพอใจมาก แต่การเขียนโค้ดที่รันบนอุปกรณ์หลายเครื่องที่สื่อสารระหว่างกันนั้นเป็นการยืนยันชีวิต บทความนี้จะสอนวิธีเชื่อมต่อและแลกเปลี่ยนข้อความผ่านเครือข่ายโดยใช้ Transmission Control Protocol (TCP)

ในบทความนี้ คุณจะต้องตั้งค่าแอปพลิเคชันที่จะเชื่อมต่อคอมพิวเตอร์ของคุณเข้ากับตัวมันเอง และโดยพื้นฐานแล้ว ทำให้มันคลั่งไคล้ - พูดคุยกับตัวเอง คุณจะได้เรียนรู้ถึงความแตกต่างระหว่างสองสตรีมที่ใช้กันอย่างแพร่หลายมากที่สุดสำหรับการสร้างเครือข่ายใน Java และวิธีการทำงาน

ข้อมูลและสตรีมออบเจ็กต์

ก่อนดำดิ่งลงไปในโค้ด จำเป็นต้องแยกแยะความแตกต่างระหว่างสองสตรีมที่ใช้ในบทความ

สตรีมข้อมูล

สตรีมข้อมูลประมวลผลประเภทข้อมูลดั้งเดิมและสตริง ข้อมูลที่ส่งผ่านสตรีมข้อมูลจะต้องถูกทำให้เป็นอนุกรมและดีซีเรียลไลซ์ด้วยตนเอง ซึ่งทำให้ยากต่อการถ่ายโอนข้อมูลที่ซับซ้อน แต่สตรีมข้อมูลสามารถสื่อสารกับเซิร์ฟเวอร์และไคลเอ็นต์ที่เขียนในภาษาอื่นที่ไม่ใช่ Java สตรีมข้อมูลดิบจะคล้ายกับสตรีมข้อมูลในด้านนั้น แต่สตรีมข้อมูลช่วยให้มั่นใจว่าข้อมูลได้รับการจัดรูปแบบในวิธีที่เป็นอิสระจากแพลตฟอร์ม ซึ่งจะเป็นประโยชน์เนื่องจากทั้งสองฝ่ายจะสามารถอ่านข้อมูลที่ส่งได้

สตรีมออบเจ็กต์

สตรีมออบเจ็กต์ประมวลผลประเภทข้อมูลดั้งเดิมและออบเจ็กต์ที่ใช้

ทำให้เป็นอนุกรมได้

อินเตอร์เฟซ. ข้อมูลที่ส่งผ่านสตรีมออบเจ็กต์จะถูกทำให้เป็นอนุกรมและดีซีเรียลไลซ์โดยอัตโนมัติ ซึ่งช่วยให้ถ่ายโอนข้อมูลที่ซับซ้อนได้ง่ายขึ้น แต่สตรีมอ็อบเจ็กต์สามารถสื่อสารกับเซิร์ฟเวอร์และไคลเอ็นต์ที่เขียนด้วยภาษาจาวาเท่านั้น อีกด้วย,

ObjectOutputStream

เมื่อเริ่มต้น จะส่งส่วนหัวไปที่

InputStream

ของอีกฝ่ายหนึ่งซึ่งเมื่อเริ่มต้นจะบล็อกการดำเนินการจนกว่าจะได้รับส่วนหัว

ขั้นตอน

สร้างแอปพลิเคชันเครือข่ายใน Java Step1
สร้างแอปพลิเคชันเครือข่ายใน Java Step1

ขั้นตอนที่ 1 สร้างชั้นเรียน

สร้างชั้นเรียนและตั้งชื่อตามต้องการ ในบทความนี้จะมีชื่อว่า

NetworkAppExample

NetworkAppExample คลาสสาธารณะ { }

สร้างแอปพลิเคชันเครือข่ายใน Java Step2
สร้างแอปพลิเคชันเครือข่ายใน Java Step2

ขั้นตอนที่ 2 สร้างวิธีการหลัก

สร้างวิธีการหลักและประกาศว่าอาจมีข้อยกเว้นของ

ข้อยกเว้น

ประเภทและคลาสย่อยของมัน - ข้อยกเว้นทั้งหมด นี่ถือเป็นการปฏิบัติที่ไม่ดี แต่เป็นที่ยอมรับสำหรับตัวอย่างแบร์โบน

NetworkAppExample คลาสสาธารณะ { โมฆะคงที่สาธารณะหลัก (สตริง args) พ่นข้อยกเว้น { } }

สร้างแอปพลิเคชันเครือข่ายใน Java Step3
สร้างแอปพลิเคชันเครือข่ายใน Java Step3

ขั้นตอนที่ 3 ประกาศที่อยู่เซิร์ฟเวอร์

ตัวอย่างนี้จะใช้ที่อยู่โฮสต์ในเครื่องและหมายเลขพอร์ตที่กำหนดเอง หมายเลขพอร์ตต้องอยู่ในช่วงตั้งแต่ 0 ถึง 65535 (รวม) อย่างไรก็ตาม หมายเลขพอร์ตเพื่อหลีกเลี่ยงช่วงตั้งแต่ 0 ถึง 1023 (รวม) เนื่องจากเป็นพอร์ตระบบที่สงวนไว้

NetworkAppExample คลาสสาธารณะ { โมฆะสาธารณะหลัก (สตริง args) พ่นข้อยกเว้น { โฮสต์สตริง = "localhost"; พอร์ต int = 10430; } }

สร้างแอปพลิเคชันเครือข่ายใน Java Step4
สร้างแอปพลิเคชันเครือข่ายใน Java Step4

ขั้นตอนที่ 4 สร้างเซิร์ฟเวอร์

เซิร์ฟเวอร์ถูกผูกไว้กับที่อยู่และพอร์ตและรับฟังการเชื่อมต่อขาเข้า ในชวา

ServerSocket

แสดงถึงปลายทางฝั่งเซิร์ฟเวอร์และหน้าที่ของมันคือการยอมรับการเชื่อมต่อใหม่

ServerSocket

ไม่มีสตรีมสำหรับอ่านและส่งข้อมูลเนื่องจากไม่ได้แสดงถึงการเชื่อมต่อระหว่างเซิร์ฟเวอร์และไคลเอ็นต์

นำเข้า java.net. InetAddress; นำเข้า java.net. ServerSocket; NetworkAppExample คลาสสาธารณะ { โมฆะสาธารณะหลัก (สตริง args) พ่นข้อยกเว้น { โฮสต์สตริง = "localhost"; พอร์ต int = 10430; เซิร์ฟเวอร์ ServerSocket = ServerSocket ใหม่ (พอร์ต 50, InetAddress.getByName (โฮสต์)); } }

สร้างแอปพลิเคชันเครือข่ายใน Java Step5
สร้างแอปพลิเคชันเครือข่ายใน Java Step5

ขั้นตอนที่ 5. บันทึกการเริ่มต้นเซิร์ฟเวอร์

เพื่อวัตถุประสงค์ในการบันทึก ให้พิมพ์ไปยังคอนโซลที่เซิร์ฟเวอร์เริ่มทำงาน

นำเข้า java.net. InetAddress; นำเข้า java.net. ServerSocket; NetworkAppExample คลาสสาธารณะ { โมฆะสาธารณะหลัก (สตริง args) พ่นข้อยกเว้น { โฮสต์สตริง = "localhost"; พอร์ต int = 10430; เซิร์ฟเวอร์ ServerSocket = ServerSocket ใหม่ (พอร์ต 50, InetAddress.getByName (โฮสต์)); System.out.println("เซิร์ฟเวอร์เริ่มทำงาน"); } }

สร้างแอปพลิเคชันเครือข่ายใน Java Step6
สร้างแอปพลิเคชันเครือข่ายใน Java Step6

ขั้นตอนที่ 6 สร้างลูกค้า

ไคลเอ็นต์ถูกผูกไว้กับที่อยู่และพอร์ตของเซิร์ฟเวอร์และรับฟังแพ็กเก็ต (ข้อความ) หลังจากสร้างการเชื่อมต่อ ในชวา

เบ้า

หมายถึงปลายทางฝั่งไคลเอ็นต์ที่เชื่อมต่อกับเซิร์ฟเวอร์หรือการเชื่อมต่อ (จากเซิร์ฟเวอร์) ไปยังไคลเอนต์และใช้เพื่อสื่อสารกับฝ่ายอื่น ๆ

นำเข้า java.net. InetAddress; นำเข้า java.net. ServerSocket; นำเข้า java.net. Socket; NetworkAppExample คลาสสาธารณะ { โมฆะสาธารณะหลัก (สตริง args) พ่นข้อยกเว้น { โฮสต์สตริง = "localhost"; พอร์ต int = 10430; เซิร์ฟเวอร์ ServerSocket = ServerSocket ใหม่ (พอร์ต 50, InetAddress.getByName (โฮสต์)); System.out.println("เซิร์ฟเวอร์เริ่มทำงาน"); ไคลเอนต์ซ็อกเก็ต = ซ็อกเก็ตใหม่ (โฮสต์ พอร์ต); } }

สร้างแอปพลิเคชันเครือข่ายใน Java Step7
สร้างแอปพลิเคชันเครือข่ายใน Java Step7

ขั้นตอนที่ 7 บันทึกความพยายามในการเชื่อมต่อ

เพื่อวัตถุประสงค์ในการบันทึก ให้พิมพ์ไปยังคอนโซลที่มีการพยายามเชื่อมต่อ

นำเข้า java.net. InetAddress; นำเข้า java.net. ServerSocket; นำเข้า java.net. Socket; NetworkAppExample คลาสสาธารณะ { โมฆะสาธารณะหลัก (สตริง args) พ่นข้อยกเว้น { โฮสต์สตริง = "localhost"; พอร์ต int = 10430; เซิร์ฟเวอร์ ServerSocket = ServerSocket ใหม่ (พอร์ต 50, InetAddress.getByName (โฮสต์)); System.out.println("เซิร์ฟเวอร์เริ่มทำงาน"); ไคลเอนต์ซ็อกเก็ต = ซ็อกเก็ตใหม่ (โฮสต์ พอร์ต); System.out.println("กำลังเชื่อมต่อกับเซิร์ฟเวอร์…"); } }

สร้างแอปพลิเคชันเครือข่ายใน Java Step8
สร้างแอปพลิเคชันเครือข่ายใน Java Step8

ขั้นตอนที่ 8 สร้างการเชื่อมต่อ

ลูกค้าจะไม่เชื่อมต่อจนกว่าเซิร์ฟเวอร์จะรับฟังและยอมรับ กล่าวอีกนัยหนึ่งคือ สร้างการเชื่อมต่อ ใน Java การเชื่อมต่อถูกสร้างขึ้นโดยใช้

ยอมรับ()

วิธีการของ

ServerSocket

ระดับ. เมธอดจะบล็อกการดำเนินการจนกว่าไคลเอ็นต์จะเชื่อมต่อ

นำเข้า java.net. InetAddress; นำเข้า java.net. ServerSocket; นำเข้า java.net. Socket; NetworkAppExample คลาสสาธารณะ { โมฆะสาธารณะหลัก (สตริง args) พ่นข้อยกเว้น { โฮสต์สตริง = "localhost"; พอร์ต int = 10430; เซิร์ฟเวอร์ ServerSocket = ServerSocket ใหม่ (พอร์ต 50, InetAddress.getByName (โฮสต์)); System.out.println("เซิร์ฟเวอร์เริ่มทำงาน"); ไคลเอนต์ซ็อกเก็ต = ซ็อกเก็ตใหม่ (โฮสต์ พอร์ต); System.out.println("กำลังเชื่อมต่อกับเซิร์ฟเวอร์…"); การเชื่อมต่อซ็อกเก็ต = server.accept(); } }

สร้างแอปพลิเคชันเครือข่ายใน Java Step9
สร้างแอปพลิเคชันเครือข่ายใน Java Step9

ขั้นตอนที่ 9 บันทึกการเชื่อมต่อที่สร้างไว้

เพื่อวัตถุประสงค์ในการบันทึก ให้พิมพ์ไปยังคอนโซลที่มีการสร้างการเชื่อมต่อระหว่างเซิร์ฟเวอร์และไคลเอนต์

นำเข้า java.net. InetAddress; นำเข้า java.net. ServerSocket; นำเข้า java.net. Socket; NetworkAppExample คลาสสาธารณะ { โมฆะสาธารณะหลัก (สตริง args) พ่นข้อยกเว้น { โฮสต์สตริง = "localhost"; พอร์ต int = 10430; เซิร์ฟเวอร์ ServerSocket = ServerSocket ใหม่ (พอร์ต 50, InetAddress.getByName (โฮสต์)); System.out.println("เซิร์ฟเวอร์เริ่มทำงาน"); ไคลเอนต์ซ็อกเก็ต = ซ็อกเก็ตใหม่ (โฮสต์ พอร์ต); System.out.println("กำลังเชื่อมต่อกับเซิร์ฟเวอร์…"); การเชื่อมต่อซ็อกเก็ต = server.accept(); System.out.println("เชื่อมต่อเรียบร้อยแล้ว"); } }

สร้างแอปพลิเคชันเครือข่ายใน Java Step10
สร้างแอปพลิเคชันเครือข่ายใน Java Step10

ขั้นตอนที่ 10 เตรียมสตรีมการสื่อสาร

การสื่อสารเสร็จสิ้นผ่านสตรีม และในแอปพลิเคชันนี้ สตรีมดิบของ (การเชื่อมต่อจาก) เซิร์ฟเวอร์ (ไปยังไคลเอ็นต์) และไคลเอ็นต์จะต้องเชื่อมโยงกับสตรีมข้อมูลหรือออบเจ็กต์ จำไว้ว่าทั้งสองฝ่ายต้องใช้สตรีมประเภทเดียวกัน

  • สตรีมข้อมูล

    นำเข้า java.io. DataInputStream; นำเข้า java.io. DataOutputStream; นำเข้า java.net. InetAddress; นำเข้า java.net. ServerSocket; นำเข้า java.net. Socket; NetworkAppExample คลาสสาธารณะ { โมฆะสาธารณะหลัก (สตริง args) พ่นข้อยกเว้น { โฮสต์สตริง = "localhost"; พอร์ต int = 10430; เซิร์ฟเวอร์ ServerSocket = ServerSocket ใหม่ (พอร์ต 50, InetAddress.getByName (โฮสต์)); System.out.println("เซิร์ฟเวอร์เริ่มทำงาน"); ไคลเอนต์ซ็อกเก็ต = ซ็อกเก็ตใหม่ (โฮสต์ พอร์ต); System.out.println("กำลังเชื่อมต่อกับเซิร์ฟเวอร์…"); การเชื่อมต่อซ็อกเก็ต = server.accept(); System.out.println("เชื่อมต่อเรียบร้อยแล้ว"); DataOutputStream clientOut = DataOutputStream ใหม่ (client.getOutputStream()); DataInputStream clientIn = ใหม่ DataInputStream(client.getInputStream()); DataOutputStream serverOut = ใหม่ DataOutputStream(connection.getOutputStream()); DataInputStream serverIn = ใหม่ DataInputStream(connection.getInputStream()); } }

  • สตรีมออบเจ็กต์

    เมื่อใช้สตรีมออบเจ็กต์หลายรายการ สตรีมอินพุตจะต้องเริ่มต้นในลำดับเดียวกันกับสตรีมเอาต์พุตเนื่องจาก

    ObjectOutputStream

    ส่งหัวให้อีกฝ่ายและ

    ObjectInputStream

    บล็อกการดำเนินการจนกว่าจะอ่านส่วนหัว

    นำเข้า java.io. ObjectInputStream; นำเข้า java.io. ObjectOutputStream; นำเข้า java.net. InetAddress; นำเข้า java.net. ServerSocket; นำเข้า java.net. Socket; NetworkAppExample คลาสสาธารณะ { โมฆะสาธารณะหลัก (สตริง args) พ่นข้อยกเว้น { โฮสต์สตริง = "localhost"; พอร์ต int = 10430; เซิร์ฟเวอร์ ServerSocket = ServerSocket ใหม่ (พอร์ต 50, InetAddress.getByName (โฮสต์)); System.out.println("เซิร์ฟเวอร์เริ่มทำงาน"); ไคลเอนต์ซ็อกเก็ต = ซ็อกเก็ตใหม่ (โฮสต์ พอร์ต); System.out.println("กำลังเชื่อมต่อกับเซิร์ฟเวอร์…"); การเชื่อมต่อซ็อกเก็ต = server.accept(); System.out.println("เชื่อมต่อเรียบร้อยแล้ว"); ObjectOutputStream clientOut = ใหม่ ObjectOutputStream(client.getOutputStream()); ObjectOutputStream serverOut = ใหม่ ObjectOutputStream(connection.getOutputStream()); ObjectInputStream clientIn = ใหม่ ObjectInputStream(client.getInputStream()); ObjectInputStream serverIn = ใหม่ ObjectInputStream(connection.getInputStream()); } }

    ลำดับตามที่ระบุในโค้ดด้านบนอาจจำง่ายกว่า - เริ่มต้นสตรีมเอาต์พุตก่อน จากนั้นจึงป้อนสตรีมในลำดับเดียวกัน อย่างไรก็ตาม ลำดับอื่นสำหรับการเริ่มต้นสตรีมอ็อบเจ็กต์มีดังต่อไปนี้:

    ObjectOutputStream clientOut = ใหม่ ObjectOutputStream(client.getOutputStream()); ObjectInputStream serverIn = ใหม่ ObjectInputStream(connection.getInputStream()); ObjectOutputStream serverOut = ใหม่ ObjectOutputStream(connection.getOutputStream()); ObjectInputStream clientIn = ใหม่ ObjectInputStream(client.getInputStream());

สร้างแอปพลิเคชันเครือข่ายใน Java Step11
สร้างแอปพลิเคชันเครือข่ายใน Java Step11

ขั้นตอนที่ 11 บันทึกว่าการสื่อสารพร้อมแล้ว

เพื่อวัตถุประสงค์ในการบันทึก ให้พิมพ์ไปยังคอนโซลที่การสื่อสารพร้อม

// รหัสละเว้น นำเข้า java.net. InetAddress; นำเข้า java.net. ServerSocket; นำเข้า java.net. Socket; NetworkAppExample คลาสสาธารณะ { โมฆะสาธารณะหลัก (สตริง args) พ่นข้อยกเว้น { โฮสต์สตริง = "localhost"; พอร์ต int = 10430; เซิร์ฟเวอร์ ServerSocket = ServerSocket ใหม่ (พอร์ต 50, InetAddress.getByName (โฮสต์)); System.out.println("เซิร์ฟเวอร์เริ่มทำงาน"); ไคลเอนต์ซ็อกเก็ต = ซ็อกเก็ตใหม่ (โฮสต์ พอร์ต); System.out.println("กำลังเชื่อมต่อกับเซิร์ฟเวอร์…"); การเชื่อมต่อซ็อกเก็ต = server.accept(); System.out.println("เชื่อมต่อเรียบร้อยแล้ว"); // รหัสละเว้น System.out.println ("การสื่อสารพร้อมแล้ว"); } }

สร้างแอปพลิเคชันเครือข่ายใน Java Step12
สร้างแอปพลิเคชันเครือข่ายใน Java Step12

ขั้นตอนที่ 12. สร้างข้อความ

ในแอปพลิเคชั่นนี้

สวัสดีชาวโลก

ข้อความจะถูกส่งไปยังเซิร์ฟเวอร์เช่น

ไบต์

หรือ

สตริง

. ประกาศตัวแปรประเภทที่ขึ้นอยู่กับกระแสที่ใช้ ใช้

ไบต์

สำหรับสตรีมข้อมูลและ

สตริง

สำหรับสตรีมวัตถุ

  • สตรีมข้อมูล

    การใช้สตรีมข้อมูล การทำให้เป็นอนุกรมทำได้โดยการแปลงออบเจ็กต์เป็นประเภทข้อมูลดั้งเดิมหรือ a

    สตริง

    . ในกรณีนี้,

    สตริง

    ถูกแปลงเป็น

    ไบต์

    แทนที่จะเขียนโดยใช้

    เขียนไบต์ ()

    เพื่อแสดงวิธีการทำกับวัตถุอื่นๆ เช่น รูปภาพ หรือไฟล์อื่นๆ

    นำเข้า java.io. DataInputStream; นำเข้า java.io. DataOutputStream; นำเข้า java.net. InetAddress; นำเข้า java.net. ServerSocket; นำเข้า java.net. Socket; NetworkAppExample คลาสสาธารณะ { โมฆะสาธารณะหลัก (สตริง args) พ่นข้อยกเว้น { โฮสต์สตริง = "localhost"; พอร์ต int = 10430; เซิร์ฟเวอร์ ServerSocket = ServerSocket ใหม่ (พอร์ต 50, InetAddress.getByName (โฮสต์)); System.out.println("เซิร์ฟเวอร์เริ่มทำงาน"); ไคลเอนต์ซ็อกเก็ต = ซ็อกเก็ตใหม่ (โฮสต์ พอร์ต); System.out.println("กำลังเชื่อมต่อกับเซิร์ฟเวอร์…"); การเชื่อมต่อซ็อกเก็ต = server.accept(); System.out.println("เชื่อมต่อเรียบร้อยแล้ว"); DataOutputStream clientOut = DataOutputStream ใหม่ (client.getOutputStream()); DataInputStream clientIn = ใหม่ DataInputStream(client.getInputStream()); DataOutputStream serverOut = ใหม่ DataOutputStream(connection.getOutputStream()); DataInputStream serverIn = ใหม่ DataInputStream(connection.getInputStream()); System.out.println("การสื่อสารพร้อมแล้ว"); byte messageOut = "สวัสดีชาวโลก".getBytes(); } }

  • สตรีมออบเจ็กต์

    นำเข้า java.io. ObjectInputStream; นำเข้า java.io. ObjectOutputStream; นำเข้า java.net. InetAddress; นำเข้า java.net. ServerSocket; นำเข้า java.net. Socket; NetworkAppExample คลาสสาธารณะ { โมฆะสาธารณะหลัก (สตริง args) พ่นข้อยกเว้น { โฮสต์สตริง = "localhost"; พอร์ต int = 10430; เซิร์ฟเวอร์ ServerSocket = ServerSocket ใหม่ (พอร์ต 50, InetAddress.getByName (โฮสต์)); System.out.println("เซิร์ฟเวอร์เริ่มทำงาน"); ไคลเอนต์ซ็อกเก็ต = ซ็อกเก็ตใหม่ (โฮสต์ พอร์ต); System.out.println("กำลังเชื่อมต่อกับเซิร์ฟเวอร์…"); การเชื่อมต่อซ็อกเก็ต = server.accept(); System.out.println("เชื่อมต่อเรียบร้อยแล้ว"); ObjectOutputStream clientOut = ใหม่ ObjectOutputStream(client.getOutputStream()); ObjectOutputStream serverOut = ใหม่ ObjectOutputStream(connection.getOutputStream()); ObjectInputStream clientIn = ใหม่ ObjectInputStream(client.getInputStream()); ObjectInputStream serverIn = ใหม่ ObjectInputStream(connection.getInputStream()); System.out.println("การสื่อสารพร้อมแล้ว"); String messageOut = "สวัสดีชาวโลก"; } }

สร้างแอปพลิเคชันเครือข่ายใน Java Step13
สร้างแอปพลิเคชันเครือข่ายใน Java Step13

ขั้นตอนที่ 13 ส่งข้อความ

เขียนข้อมูลไปยังเอาต์พุตสตรีมและล้างสตรีมเพื่อให้แน่ใจว่าเขียนข้อมูลทั้งหมดแล้ว

  • สตรีมข้อมูล

    ต้องส่งความยาวของข้อความก่อน เพื่อให้อีกฝ่ายรู้ว่าต้องอ่านกี่ไบต์ หลังจากที่ความยาวถูกส่งเป็นประเภทจำนวนเต็มพื้นฐาน สามารถส่งไบต์ได้

    นำเข้า java.io. DataInputStream; นำเข้า java.io. DataOutputStream; นำเข้า java.net. InetAddress; นำเข้า java.net. ServerSocket; นำเข้า java.net. Socket; NetworkAppExample คลาสสาธารณะ { โมฆะสาธารณะหลัก (สตริง args) พ่นข้อยกเว้น { โฮสต์สตริง = "localhost"; พอร์ต int = 10430; เซิร์ฟเวอร์ ServerSocket = ServerSocket ใหม่ (พอร์ต 50, InetAddress.getByName (โฮสต์)); System.out.println("เซิร์ฟเวอร์เริ่มทำงาน"); ไคลเอนต์ซ็อกเก็ต = ซ็อกเก็ตใหม่ (โฮสต์ พอร์ต); System.out.println("กำลังเชื่อมต่อกับเซิร์ฟเวอร์…"); การเชื่อมต่อซ็อกเก็ต = server.accept(); System.out.println("เชื่อมต่อเรียบร้อยแล้ว"); DataOutputStream clientOut = DataOutputStream ใหม่ (client.getOutputStream()); DataInputStream clientIn = ใหม่ DataInputStream(client.getInputStream()); DataOutputStream serverOut = ใหม่ DataOutputStream(connection.getOutputStream()); DataInputStream serverIn = ใหม่ DataInputStream(connection.getInputStream()); System.out.println("การสื่อสารพร้อมแล้ว"); byte messageOut = "สวัสดีชาวโลก".getBytes(); clientOut.writeInt(messageOut.length); clientOut.write(messageOut); clientOut.flush(); } }

  • สตรีมออบเจ็กต์

    นำเข้า java.io. ObjectInputStream; นำเข้า java.io. ObjectOutputStream; นำเข้า java.net. InetAddress; นำเข้า java.net. ServerSocket; นำเข้า java.net. Socket; NetworkAppExample คลาสสาธารณะ { โมฆะสาธารณะหลัก (สตริง args) พ่นข้อยกเว้น { โฮสต์สตริง = "localhost"; พอร์ต int = 10430; เซิร์ฟเวอร์ ServerSocket = ServerSocket ใหม่ (พอร์ต 50, InetAddress.getByName (โฮสต์)); System.out.println("เซิร์ฟเวอร์เริ่มทำงาน"); ไคลเอนต์ซ็อกเก็ต = ซ็อกเก็ตใหม่ (โฮสต์ พอร์ต); System.out.println("กำลังเชื่อมต่อกับเซิร์ฟเวอร์…"); การเชื่อมต่อซ็อกเก็ต = server.accept(); System.out.println("เชื่อมต่อเรียบร้อยแล้ว"); ObjectOutputStream clientOut = ใหม่ ObjectOutputStream(client.getOutputStream()); ObjectOutputStream serverOut = ใหม่ ObjectOutputStream(connection.getOutputStream()); ObjectInputStream clientIn = ใหม่ ObjectInputStream(client.getInputStream()); ObjectInputStream serverIn = ใหม่ ObjectInputStream(connection.getInputStream()); System.out.println("การสื่อสารพร้อมแล้ว"); String messageOut = "สวัสดีชาวโลก"; clientOut.writeObject(messageOut); clientOut.flush(); } }

สร้างแอปพลิเคชันเครือข่ายใน Java Step14
สร้างแอปพลิเคชันเครือข่ายใน Java Step14

ขั้นตอนที่ 14. บันทึกข้อความที่ส่ง

เพื่อวัตถุประสงค์ในการบันทึก ให้พิมพ์ไปยังคอนโซลที่มีการส่งข้อความ

  • สตรีมข้อมูล

    นำเข้า java.io. DataInputStream; นำเข้า java.io. DataOutputStream; นำเข้า java.net. InetAddress; นำเข้า java.net. ServerSocket; นำเข้า java.net. Socket; NetworkAppExample คลาสสาธารณะ { โมฆะสาธารณะหลัก (สตริง args) พ่นข้อยกเว้น { โฮสต์สตริง = "localhost"; พอร์ต int = 10430; เซิร์ฟเวอร์ ServerSocket = ServerSocket ใหม่ (พอร์ต 50, InetAddress.getByName (โฮสต์)); System.out.println("เซิร์ฟเวอร์เริ่มทำงาน"); ไคลเอนต์ซ็อกเก็ต = ซ็อกเก็ตใหม่ (โฮสต์ พอร์ต); System.out.println("กำลังเชื่อมต่อกับเซิร์ฟเวอร์…"); การเชื่อมต่อซ็อกเก็ต = server.accept(); System.out.println("เชื่อมต่อเรียบร้อยแล้ว"); DataOutputStream clientOut = DataOutputStream ใหม่ (client.getOutputStream()); DataInputStream clientIn = ใหม่ DataInputStream(client.getInputStream()); DataOutputStream serverOut = ใหม่ DataOutputStream(connection.getOutputStream()); DataInputStream serverIn = ใหม่ DataInputStream(connection.getInputStream()); System.out.println("การสื่อสารพร้อมแล้ว"); byte messageOut = "สวัสดีชาวโลก".getBytes(); clientOut.writeInt(messageOut.length); clientOut.write(messageOut); clientOut.flush(); System.out.println("ข้อความที่ส่งไปยังเซิร์ฟเวอร์:" + สตริงใหม่ (messageOut)); } }

  • สตรีมออบเจ็กต์

    นำเข้า java.io. ObjectInputStream; นำเข้า java.io. ObjectOutputStream; นำเข้า java.net. InetAddress; นำเข้า java.net. ServerSocket; นำเข้า java.net. Socket; NetworkAppExample คลาสสาธารณะ { โมฆะสาธารณะหลัก (สตริง args) พ่นข้อยกเว้น { โฮสต์สตริง = "localhost"; พอร์ต int = 10430; เซิร์ฟเวอร์ ServerSocket = ServerSocket ใหม่ (พอร์ต 50, InetAddress.getByName (โฮสต์)); System.out.println("เซิร์ฟเวอร์เริ่มทำงาน"); ไคลเอนต์ซ็อกเก็ต = ซ็อกเก็ตใหม่ (โฮสต์ พอร์ต); System.out.println("กำลังเชื่อมต่อกับเซิร์ฟเวอร์…"); การเชื่อมต่อซ็อกเก็ต = server.accept(); System.out.println("เชื่อมต่อเรียบร้อยแล้ว"); ObjectOutputStream clientOut = ใหม่ ObjectOutputStream(client.getOutputStream()); ObjectOutputStream serverOut = ใหม่ ObjectOutputStream(connection.getOutputStream()); ObjectInputStream clientIn = ใหม่ ObjectInputStream(client.getInputStream()); ObjectInputStream serverIn = ใหม่ ObjectInputStream(connection.getInputStream()); System.out.println("การสื่อสารพร้อมแล้ว"); String messageOut = "สวัสดีชาวโลก"; clientOut.writeObject(messageOut); clientOut.flush(); System.out.println("ข้อความที่ส่งไปยังเซิร์ฟเวอร์: " + messageOut); } }

สร้างแอปพลิเคชันเครือข่ายใน Java Step15
สร้างแอปพลิเคชันเครือข่ายใน Java Step15

ขั้นตอนที่ 15 อ่านข้อความ

อ่านข้อมูลจากสตรีมอินพุตและแปลง เนื่องจากเราทราบประเภทข้อมูลที่ส่งอย่างแน่นอน เราจะสร้าง a

สตริง

จาก

ไบต์

หรือโยน

วัตถุ

ถึง

สตริง

โดยไม่ต้องตรวจสอบขึ้นอยู่กับกระแสที่ใช้

  • สตรีมข้อมูล

    เนื่องจากความยาวถูกส่งก่อนและไบต์หลังจากนั้น การอ่านจะต้องทำในลำดับเดียวกัน ในกรณีที่ความยาวเป็นศูนย์ จะไม่มีอะไรให้อ่าน ออบเจ็กต์ถูกดีซีเรียลไลซ์เมื่อไบต์ถูกแปลงกลับเป็นอินสแตนซ์ ในกรณีนี้ ของ

    สตริง

    นำเข้า java.io. DataInputStream; นำเข้า java.io. DataOutputStream; นำเข้า java.net. InetAddress; นำเข้า java.net. ServerSocket; นำเข้า java.net. Socket; NetworkAppExample คลาสสาธารณะ { โมฆะสาธารณะหลัก (สตริง args) พ่นข้อยกเว้น { โฮสต์สตริง = "localhost"; พอร์ต int = 10430; เซิร์ฟเวอร์ ServerSocket = ServerSocket ใหม่ (พอร์ต 50, InetAddress.getByName (โฮสต์)); System.out.println("เซิร์ฟเวอร์เริ่มทำงาน"); ไคลเอนต์ซ็อกเก็ต = ซ็อกเก็ตใหม่ (โฮสต์ พอร์ต); System.out.println("กำลังเชื่อมต่อกับเซิร์ฟเวอร์…"); การเชื่อมต่อซ็อกเก็ต = server.accept(); System.out.println("เชื่อมต่อเรียบร้อยแล้ว"); DataOutputStream clientOut = DataOutputStream ใหม่ (client.getOutputStream()); DataInputStream clientIn = ใหม่ DataInputStream(client.getInputStream()); DataOutputStream serverOut = ใหม่ DataOutputStream(connection.getOutputStream()); DataInputStream serverIn = ใหม่ DataInputStream(connection.getInputStream()); System.out.println("การสื่อสารพร้อมแล้ว"); byte messageOut = "สวัสดีชาวโลก".getBytes(); clientOut.writeInt(messageOut.length); clientOut.write(messageOut); clientOut.flush(); System.out.println("ข้อความที่ส่งไปยังเซิร์ฟเวอร์:" + สตริงใหม่ (messageOut)); ความยาว int = serverIn.readInt(); ถ้า (ความยาว > 0) { ไบต์ messageIn = ไบต์ใหม่[ความยาว]; serverIn.readFully(messageIn, 0, messageIn.length); } } }

  • สตรีมออบเจ็กต์

    นำเข้า java.io. ObjectInputStream; นำเข้า java.io. ObjectOutputStream; นำเข้า java.net. InetAddress; นำเข้า java.net. ServerSocket; นำเข้า java.net. Socket; NetworkAppExample คลาสสาธารณะ { โมฆะสาธารณะหลัก (สตริง args) พ่นข้อยกเว้น { โฮสต์สตริง = "localhost"; พอร์ต int = 10430; เซิร์ฟเวอร์ ServerSocket = ServerSocket ใหม่ (พอร์ต 50, InetAddress.getByName (โฮสต์)); System.out.println("เซิร์ฟเวอร์เริ่มทำงาน"); ไคลเอนต์ซ็อกเก็ต = ซ็อกเก็ตใหม่ (โฮสต์ พอร์ต); System.out.println("กำลังเชื่อมต่อกับเซิร์ฟเวอร์…"); การเชื่อมต่อซ็อกเก็ต = server.accept(); System.out.println("เชื่อมต่อเรียบร้อยแล้ว"); ObjectOutputStream clientOut = ใหม่ ObjectOutputStream(client.getOutputStream()); ObjectOutputStream serverOut = ใหม่ ObjectOutputStream(connection.getOutputStream()); ObjectInputStream clientIn = ใหม่ ObjectInputStream(client.getInputStream()); ObjectInputStream serverIn = ใหม่ ObjectInputStream(connection.getInputStream()); System.out.println("การสื่อสารพร้อมแล้ว"); String messageOut = "สวัสดีชาวโลก"; clientOut.writeObject(messageOut); clientOut.flush(); System.out.println("ข้อความที่ส่งไปยังเซิร์ฟเวอร์: " + messageOut); ข้อความสตริง = (สตริง) serverIn.readObject (); } }

สร้างแอปพลิเคชันเครือข่ายใน Java Step16
สร้างแอปพลิเคชันเครือข่ายใน Java Step16

ขั้นตอนที่ 16 บันทึกการอ่านข้อความ

เพื่อวัตถุประสงค์ในการบันทึก ให้พิมพ์ไปยังคอนโซลที่ได้รับข้อความและพิมพ์เนื้อหา

  • สตรีมข้อมูล

    นำเข้า java.io. DataInputStream; นำเข้า java.io. DataOutputStream; นำเข้า java.net. InetAddress; นำเข้า java.net. ServerSocket; นำเข้า java.net. Socket; NetworkAppExample คลาสสาธารณะ { โมฆะสาธารณะหลัก (สตริง args) พ่นข้อยกเว้น { โฮสต์สตริง = "localhost"; พอร์ต int = 10430; เซิร์ฟเวอร์ ServerSocket = ServerSocket ใหม่ (พอร์ต 50, InetAddress.getByName (โฮสต์)); System.out.println("เซิร์ฟเวอร์เริ่มทำงาน"); ไคลเอนต์ซ็อกเก็ต = ซ็อกเก็ตใหม่ (โฮสต์ พอร์ต); System.out.println("กำลังเชื่อมต่อกับเซิร์ฟเวอร์…"); การเชื่อมต่อซ็อกเก็ต = server.accept(); System.out.println("เชื่อมต่อเรียบร้อยแล้ว"); DataOutputStream clientOut = DataOutputStream ใหม่ (client.getOutputStream()); DataInputStream clientIn = ใหม่ DataInputStream(client.getInputStream()); DataOutputStream serverOut = ใหม่ DataOutputStream(connection.getOutputStream()); DataInputStream serverIn = ใหม่ DataInputStream(connection.getInputStream()); System.out.println("การสื่อสารพร้อมแล้ว"); byte messageOut = "สวัสดีชาวโลก".getBytes(); clientOut.writeInt(messageOut.length); clientOut.write(messageOut); clientOut.flush(); System.out.println("ข้อความที่ส่งไปยังเซิร์ฟเวอร์:" + สตริงใหม่ (messageOut)); ความยาว int = serverIn.readInt(); ถ้า (ความยาว > 0) { ไบต์ messageIn = ไบต์ใหม่[ความยาว]; serverIn.readFully(messageIn, 0, messageIn.length); System.out.println("ข้อความที่ได้รับจากลูกค้า: " + สตริงใหม่ (messageIn)); } } }

  • สตรีมออบเจ็กต์

    นำเข้า java.io. ObjectInputStream; นำเข้า java.io. ObjectOutputStream; นำเข้า java.net. InetAddress; นำเข้า java.net. ServerSocket; นำเข้า java.net. Socket; NetworkAppExample คลาสสาธารณะ { โมฆะสาธารณะหลัก (สตริง args) พ่นข้อยกเว้น { โฮสต์สตริง = "localhost"; พอร์ต int = 10430; เซิร์ฟเวอร์ ServerSocket = ServerSocket ใหม่ (พอร์ต 50, InetAddress.getByName (โฮสต์)); System.out.println("เซิร์ฟเวอร์เริ่มทำงาน"); ไคลเอนต์ซ็อกเก็ต = ซ็อกเก็ตใหม่ (โฮสต์ พอร์ต); System.out.println("กำลังเชื่อมต่อกับเซิร์ฟเวอร์…"); การเชื่อมต่อซ็อกเก็ต = server.accept(); System.out.println("เชื่อมต่อเรียบร้อยแล้ว"); ObjectOutputStream clientOut = ใหม่ ObjectOutputStream(client.getOutputStream()); ObjectOutputStream serverOut = ใหม่ ObjectOutputStream(connection.getOutputStream()); ObjectInputStream clientIn = ใหม่ ObjectInputStream(client.getInputStream()); ObjectInputStream serverIn = ใหม่ ObjectInputStream(connection.getInputStream()); System.out.println("การสื่อสารพร้อมแล้ว"); String messageOut = "สวัสดีชาวโลก"; clientOut.writeObject(messageOut); clientOut.flush(); System.out.println("ข้อความที่ส่งไปยังเซิร์ฟเวอร์: " + messageOut); ข้อความสตริง = (สตริง) serverIn.readObject (); System.out.println("ข้อความที่ได้รับจากลูกค้า: " + messageIn); } }

สร้างแอปพลิเคชันเครือข่ายใน Java Step17
สร้างแอปพลิเคชันเครือข่ายใน Java Step17

ขั้นตอนที่ 17. ตัดการเชื่อมต่อ

การเชื่อมต่อถูกตัดการเชื่อมต่อเมื่อฝ่ายหนึ่งปิดสตรีมของตน ใน Java การปิดเอาต์พุตสตรีม ซ็อกเก็ตที่เกี่ยวข้องและอินพุตสตรีมจะปิดเช่นกัน เมื่ออีกฝ่ายหนึ่งพบว่าการเชื่อมต่อไม่ทำงาน จะต้องปิดสตรีมเอาต์พุตด้วยเพื่อป้องกันหน่วยความจำรั่ว

// รหัสละเว้น นำเข้า java.net. InetAddress; นำเข้า java.net. ServerSocket; นำเข้า java.net. Socket; NetworkAppExample คลาสสาธารณะ { โมฆะสาธารณะหลัก (สตริง args) พ่นข้อยกเว้น { โฮสต์สตริง = "localhost"; พอร์ต int = 10430; เซิร์ฟเวอร์ ServerSocket = ServerSocket ใหม่ (พอร์ต 50, InetAddress.getByName (โฮสต์)); System.out.println("เซิร์ฟเวอร์เริ่มทำงาน"); ไคลเอนต์ซ็อกเก็ต = ซ็อกเก็ตใหม่ (โฮสต์ พอร์ต); System.out.println("กำลังเชื่อมต่อกับเซิร์ฟเวอร์…"); การเชื่อมต่อซ็อกเก็ต = server.accept(); System.out.println("เชื่อมต่อเรียบร้อยแล้ว"); // รหัสละเว้น System.out.println ("การสื่อสารพร้อมแล้ว"); // รหัสละเว้น clientOut.close(); serverOut.close(); } }

สร้างแอปพลิเคชันเครือข่ายใน Java Step18 V2
สร้างแอปพลิเคชันเครือข่ายใน Java Step18 V2

ขั้นตอนที่ 18 บันทึกการตัดการเชื่อมต่อ

เพื่อวัตถุประสงค์ในการบันทึก การพิมพ์ไปยังการเชื่อมต่อคอนโซลถูกยกเลิกการเชื่อมต่อ

// รหัสละเว้น นำเข้า java.net. InetAddress; นำเข้า java.net. ServerSocket; นำเข้า java.net. Socket; NetworkAppExample คลาสสาธารณะ { โมฆะสาธารณะหลัก (สตริง args) พ่นข้อยกเว้น { โฮสต์สตริง = "localhost"; พอร์ต int = 10430; เซิร์ฟเวอร์ ServerSocket = ServerSocket ใหม่ (พอร์ต 50, InetAddress.getByName (โฮสต์)); System.out.println("เซิร์ฟเวอร์เริ่มทำงาน"); ไคลเอนต์ซ็อกเก็ต = ซ็อกเก็ตใหม่ (โฮสต์ พอร์ต); System.out.println("กำลังเชื่อมต่อกับเซิร์ฟเวอร์…"); การเชื่อมต่อซ็อกเก็ต = server.accept(); System.out.println("เชื่อมต่อเรียบร้อยแล้ว"); // รหัสละเว้น System.out.println ("การสื่อสารพร้อมแล้ว"); // รหัสละเว้น clientOut.close(); serverOut.close(); System.out.println("ปิดการเชื่อมต่อ"); } }

สร้างแอปพลิเคชันเครือข่ายใน Java Step19
สร้างแอปพลิเคชันเครือข่ายใน Java Step19

ขั้นตอนที่ 19. ยุติเซิร์ฟเวอร์

การเชื่อมต่อถูกตัดการเชื่อมต่อ แต่เซิร์ฟเวอร์ยังคงทำงานอยู่ เนื่องจาก

ServerSocket

ไม่ได้เชื่อมโยงกับสตรีมใด ๆ จะต้องปิดอย่างชัดเจนโดยการโทร

ปิด()

กระบวนการ.

// รหัสละเว้น นำเข้า java.net. InetAddress; นำเข้า java.net. ServerSocket; นำเข้า java.net. Socket; NetworkAppExample คลาสสาธารณะ { โมฆะสาธารณะหลัก (สตริง args) พ่นข้อยกเว้น { โฮสต์สตริง = "localhost"; พอร์ต int = 10430; เซิร์ฟเวอร์ ServerSocket = ServerSocket ใหม่ (พอร์ต 50, InetAddress.getByName (โฮสต์)); System.out.println("เซิร์ฟเวอร์เริ่มทำงาน"); ไคลเอนต์ซ็อกเก็ต = ซ็อกเก็ตใหม่ (โฮสต์ พอร์ต); System.out.println("กำลังเชื่อมต่อกับเซิร์ฟเวอร์…"); การเชื่อมต่อซ็อกเก็ต = server.accept(); System.out.println("เชื่อมต่อเรียบร้อยแล้ว"); // รหัสละเว้น System.out.println ("การสื่อสารพร้อมแล้ว"); // รหัสละเว้น clientOut.close(); serverOut.close(); System.out.println("ปิดการเชื่อมต่อ"); เซิร์ฟเวอร์.close(); } }

สร้างแอปพลิเคชันเครือข่ายใน Java Step20
สร้างแอปพลิเคชันเครือข่ายใน Java Step20

ขั้นตอนที่ 20. บันทึกการยกเลิกเซิร์ฟเวอร์

เพื่อวัตถุประสงค์ในการบันทึก การพิมพ์ไปยังคอนโซลเซิร์ฟเวอร์ถูกยกเลิก

// รหัสละเว้น นำเข้า java.net. InetAddress; นำเข้า java.net. ServerSocket; นำเข้า java.net. Socket; NetworkAppExample คลาสสาธารณะ { โมฆะสาธารณะหลัก (สตริง args) พ่นข้อยกเว้น { โฮสต์สตริง = "localhost"; พอร์ต int = 10430; เซิร์ฟเวอร์ ServerSocket = ServerSocket ใหม่ (พอร์ต 50, InetAddress.getByName (โฮสต์)); System.out.println("เซิร์ฟเวอร์เริ่มทำงาน"); ไคลเอนต์ซ็อกเก็ต = ซ็อกเก็ตใหม่ (โฮสต์ พอร์ต); System.out.println("กำลังเชื่อมต่อกับเซิร์ฟเวอร์…"); การเชื่อมต่อซ็อกเก็ต = server.accept(); System.out.println("เชื่อมต่อเรียบร้อยแล้ว"); // รหัสละเว้น System.out.println ("การสื่อสารพร้อมแล้ว"); // รหัสละเว้น clientOut.close(); serverOut.close(); System.out.println("ปิดการเชื่อมต่อ"); เซิร์ฟเวอร์.close(); System.out.println("เซิร์ฟเวอร์ถูกยกเลิก"); } }

สร้างแอปพลิเคชันเครือข่ายใน Java Step21
สร้างแอปพลิเคชันเครือข่ายใน Java Step21

ขั้นตอนที่ 21 รวบรวมและเรียกใช้

การบันทึกช่วยให้เราทราบว่าแอปพลิเคชันประสบความสำเร็จหรือไม่ ผลผลิตที่คาดหวัง:

เซิร์ฟเวอร์เริ่มทำงาน กำลังเชื่อมต่อกับเซิร์ฟเวอร์… การเชื่อมต่อถูกสร้างขึ้น การสื่อสารพร้อมแล้ว ข้อความที่ส่งไปยังเซิร์ฟเวอร์: Hello World ข้อความที่ได้รับจากลูกค้า: ปิดการเชื่อมต่อ Hello World เซิร์ฟเวอร์ถูกยกเลิก

ในกรณีที่ผลลัพธ์ของคุณไม่เหมือนกับด้านบน ซึ่งไม่น่าจะเกิดขึ้น มีวิธีแก้ปัญหาสองสามข้อ:

  • ถ้าเอาท์พุตหยุดที่เส้น

    สร้างการเชื่อมต่อแล้ว

    และมีการใช้สตรีมออบเจ็กต์ ล้างแต่ละอัน

    ObjectOutputStream

  • ทันทีหลังจากเริ่มต้นเนื่องจากไม่ได้ส่งส่วนหัวด้วยเหตุผลบางประการ
  • หากผลงานพิมพ์

    java.net. BindException: มีการใช้ที่อยู่นี้แล้ว

  • ให้เลือกหมายเลขพอร์ตอื่นเนื่องจากหมายเลขที่ระบุถูกใช้ไปแล้ว

เคล็ดลับ

  • การเชื่อมต่อกับเซิร์ฟเวอร์บนเครือข่ายอื่นทำได้โดยการเชื่อมต่อกับที่อยู่ IP ภายนอกของอุปกรณ์ที่ใช้เซิร์ฟเวอร์ที่มีพอร์ตที่ส่งต่อ
  • การเชื่อมต่อกับเซิร์ฟเวอร์ในเครือข่ายเดียวกันทำได้โดยเชื่อมต่อกับที่อยู่ IP ส่วนตัวของอุปกรณ์ที่ใช้เซิร์ฟเวอร์หรือส่งต่อพอร์ตและเชื่อมต่อกับที่อยู่ IP ภายนอกของอุปกรณ์
  • มีซอฟต์แวร์ เช่น Hamachi ที่อนุญาตให้เชื่อมต่อกับเซิร์ฟเวอร์ในเครือข่ายอื่นโดยไม่ต้องส่งต่อพอร์ต แต่ต้องมีการติดตั้งซอฟต์แวร์บนอุปกรณ์ทั้งสอง

ตัวอย่าง

แอปพลิเคชันเครือข่ายที่ใช้การบล็อกอินพุต/เอาต์พุตจำเป็นต้องใช้เธรด ตัวอย่างต่อไปนี้แสดงการใช้งานเซิร์ฟเวอร์และไคลเอนต์แบบมินิมอลด้วยเธรด โดยพื้นฐานแล้วรหัสเครือข่ายจะเหมือนกับในบทความ ยกเว้นบางตัวอย่างถูกซิงโครไนซ์ ย้ายไปยังเธรด และจัดการข้อยกเว้น

Server.java

นำเข้า java.io. IOException; นำเข้า java.net. InetAddress; นำเข้า java.net. ServerSocket; นำเข้า java.net. SocketException; นำเข้า java.net. UnknownHostException; นำเข้า java.util. ArrayList; นำเข้า java.util. Collections; นำเข้า java.util. List; /** * คลาส {@code Server} แสดงถึงจุดสิ้นสุดของเซิร์ฟเวอร์ในเครือข่าย {@code Server} เมื่อผูกกับที่อยู่ IP * และพอร์ตที่กำหนดแล้ว จะทำการเชื่อมต่อกับไคลเอ็นต์และสามารถสื่อสารกับพวกเขาหรือยกเลิกการเชื่อมต่อได้ *

* คลาสนี้เป็น threadsafe * * @version 1.0 * @see Client * @see Connection */ คลาสสาธารณะ เซิร์ฟเวอร์ใช้ Runnable { เซิร์ฟเวอร์ ServerSocket ส่วนตัว; รายการส่วนตัว การเชื่อมต่อ; เธรดเธรดส่วนตัว ส่วนตัวสุดท้าย Object connectionsLock = new Object(); /** * สร้าง {@code Server} ที่โต้ตอบกับไคลเอ็นต์บนชื่อโฮสต์และพอร์ตที่ระบุโดยมี * ร้องขอความยาวสูงสุดของคิวไคลเอ็นต์ขาเข้า * * @param host ที่อยู่โฮสต์ที่จะใช้ * @param port หมายเลขพอร์ตที่จะใช้ * @param backlog ขอความยาวสูงสุดของคิวของลูกค้าที่เข้ามา * @throws NetworkException หากเกิดข้อผิดพลาดขณะเริ่มเซิร์ฟเวอร์ */ เซิร์ฟเวอร์สาธารณะ (โฮสต์สตริง, พอร์ต int, งานค้าง int) พ่น NetworkException { ลอง { เซิร์ฟเวอร์ = ใหม่ ServerSocket (พอร์ต, งานในมือ, InetAddress.getByName (โฮสต์)); } catch (UnknownHostException e) { โยน NetworkException ใหม่ ("ชื่อโฮสต์ไม่สามารถแก้ไขได้: " + โฮสต์ e); } catch (IllegalArgumentException e) { โยน NetworkException ใหม่ ("หมายเลขพอร์ตต้องอยู่ระหว่าง 0 ถึง 65535 (รวม): " + พอร์ต); } catch (IOException e) { โยน NetworkException ใหม่ ("เซิร์ฟเวอร์ไม่สามารถเริ่มต้นได้", e); } การเชื่อมต่อ = Collections.synchronizedList(new ArrayList()); เธรด = เธรดใหม่ (นี้); thread.start(); } /** * สร้าง {@code Server} ที่โต้ตอบกับไคลเอ็นต์บนชื่อโฮสต์และพอร์ตที่ระบุ * * @param โฮสต์ ที่อยู่โฮสต์ที่จะผูก * @param port หมายเลขพอร์ตที่จะผูก * @throws NetworkException หากเกิดข้อผิดพลาดขณะเริ่มต้นเซิร์ฟเวอร์ */ เซิร์ฟเวอร์สาธารณะ (โฮสต์สตริง, พอร์ต int) โยน NetworkException { นี่ (โฮสต์, พอร์ต, 50); } /** * รับฟัง ยอมรับ และลงทะเบียนการเชื่อมต่อขาเข้าจากลูกค้า */ @Override public void run() { while (!server.isClosed()) { ลอง { connections.add(new Connection(server.accept())); } จับ (SocketException e) { if (!e.getMessage().equals("Socket closed")) { e.printStackTrace(); } } จับ (NetworkException | IOException จ) { e.printStackTrace (); } } } /** * ส่งข้อมูลไปยังลูกค้าที่ลงทะเบียนทั้งหมด * * @param data data ที่จะส่ง * @throws IllegalStateException หากพยายามเขียนข้อมูลเมื่อเซิร์ฟเวอร์ออฟไลน์ * @throws IllegalArgumentException หากข้อมูลที่ส่งเป็นโมฆะ */ การออกอากาศโมฆะสาธารณะ (ข้อมูลออบเจ็กต์) { if (server.isClosed ()) { โยน IllegalStateException ใหม่ ("ไม่ได้ส่งข้อมูล เซิร์ฟเวอร์ออฟไลน์อยู่"); } if (data == null) { โยน IllegalArgumentException ใหม่ ("null data"); } ซิงโครไนซ์ (connectionsLock) { สำหรับ (การเชื่อมต่อการเชื่อมต่อ: การเชื่อมต่อ) { ลอง { connection.send (data); System.out.println("ข้อมูลที่ส่งไปยังไคลเอนต์เรียบร้อยแล้ว"); } จับ (NetworkException จ) { e.printStackTrace (); } } } } /** * ส่งข้อความยกเลิกการเชื่อมต่อและยกเลิกการเชื่อมต่อไคลเอ็นต์ที่ระบุ * * ไคลเอ็นต์การเชื่อมต่อ @param เพื่อยกเลิกการเชื่อมต่อ * @throws NetworkException หากเกิดข้อผิดพลาดขณะปิดการเชื่อมต่อ */ การยกเลิกการเชื่อมต่อเป็นโมฆะสาธารณะ (การเชื่อมต่อการเชื่อมต่อ) พ่น NetworkException { ถ้า (connections.remove (การเชื่อมต่อ)) { connection.close (); } } /** * ส่งข้อความยกเลิกการเชื่อมต่อไปยังไคลเอนต์ทั้งหมด ตัดการเชื่อมต่อ และยกเลิกเซิร์ฟเวอร์ */ ปิดโมฆะสาธารณะ () พ่น NetworkException { ซิงโครไนซ์ (connectionsLock) { สำหรับ (การเชื่อมต่อการเชื่อมต่อ: การเชื่อมต่อ) { ลอง { connection.close (); } จับ (NetworkException จ) { e.printStackTrace (); } } } การเชื่อมต่อ clear(); ลอง { server.close(); } catch (IOException e) { โยน NetworkException ใหม่ ("เกิดข้อผิดพลาดขณะปิดเซิร์ฟเวอร์"); } ในที่สุด { thread.interrupt(); } } /** * ส่งกลับว่าเซิร์ฟเวอร์ออนไลน์อยู่หรือไม่ * * @return True หากเซิร์ฟเวอร์ออนไลน์อยู่ เท็จมิฉะนั้น */ isOnline บูลีนสาธารณะ () { return !server.isClosed(); } /** * ส่งกลับอาร์เรย์ของลูกค้าที่ลงทะเบียน */ การเชื่อมต่อสาธารณะ getConnections () { ซิงโครไนซ์ (connectionsLock) { ส่งคืนการเชื่อมต่อ.toArray (การเชื่อมต่อใหม่ [connections.size ()]); } } }

Client.java

นำเข้า java.io. IOException; นำเข้า java.net. Socket; นำเข้า java.net. UnknownHostException; /** * คลาส {@code Client} แสดงถึงปลายทางของไคลเอ็นต์ในเครือข่าย {@code Client} เมื่อเชื่อมต่อกับเซิร์ฟเวอร์ * บางตัวแล้ว รับประกันว่าจะสามารถสื่อสารกับเซิร์ฟเวอร์ได้เท่านั้น ลูกค้ารายอื่นจะได้รับข้อมูลหรือไม่ * ขึ้นอยู่กับการใช้งานเซิร์ฟเวอร์ *

* คลาสนี้เป็น threadsafe * * @version 1.0 * @see Server * @see Connection */ ไคลเอ็นต์คลาสสาธารณะ { การเชื่อมต่อการเชื่อมต่อส่วนตัว; /** * สร้าง {@code Client} ที่เชื่อมต่อกับเซิร์ฟเวอร์บนโฮสต์และพอร์ตที่ระบุ * * @param โฮสต์ ที่อยู่โฮสต์ที่จะผูก * @param port หมายเลขพอร์ตที่จะผูก * @throws NetworkException หากเกิดข้อผิดพลาดขณะเริ่มเซิร์ฟเวอร์ */ ไคลเอนต์สาธารณะ (โฮสต์สตริง, พอร์ต int) พ่น NetworkException { ลอง { การเชื่อมต่อ = การเชื่อมต่อใหม่ (ซ็อกเก็ตใหม่ (โฮสต์, พอร์ต)); } catch (UnknownHostException e) { โยน NetworkException ใหม่ ("ชื่อโฮสต์ไม่สามารถแก้ไขได้: " + โฮสต์ e); } catch (IllegalArgumentException e) { โยน NetworkException ใหม่ ("หมายเลขพอร์ตต้องอยู่ระหว่าง 0 ถึง 65535 (รวม): " + พอร์ต); } catch (IOException e) { โยน NetworkException ใหม่ ("เซิร์ฟเวอร์ไม่สามารถเริ่มต้นได้", e); } } /** * ส่งข้อมูลไปยังบุคคลอื่น * * @param data data ที่จะส่ง * @throws NetworkException หากการเขียนไปยังเอาต์พุตสตรีมล้มเหลว * @throws IllegalStateException หากพยายามเขียนข้อมูลเมื่อปิดการเชื่อมต่อ * @throws IllegalArgumentException หากข้อมูลที่ส่งเป็นโมฆะ * @throws UnsupportedOperationException หากพยายามส่งประเภทข้อมูลที่ไม่รองรับ */ โมฆะสาธารณะส่ง (ข้อมูลวัตถุ) พ่น NetworkException { connection.send (ข้อมูล); } /** * ส่งข้อความตัดการเชื่อมต่อไปยังและปิดการเชื่อมต่อกับเซิร์ฟเวอร์ */ ปิดโมฆะสาธารณะ () พ่น NetworkException { connection.close (); } /** * ส่งคืนว่าไคลเอ็นต์เชื่อมต่อกับเซิร์ฟเวอร์หรือไม่ * * @return True หากไคลเอนต์เชื่อมต่ออยู่ เท็จมิฉะนั้น */ isOnline บูลีนสาธารณะ () { return connection.isConnected (); } /** * ส่งคืนอินสแตนซ์ {@link Connection} ของไคลเอ็นต์ */ การเชื่อมต่อสาธารณะ getConnection() { กลับการเชื่อมต่อ; } }

Connection.java

นำเข้า java.io. DataInputStream; นำเข้า java.io. DataOutputStream; นำเข้า java.io. IOException; นำเข้า java.net. Socket; นำเข้า java.net. SocketException; /** * คลาส {@code Connection} หมายถึงการเชื่อมต่อจากเซิร์ฟเวอร์ไปยังไคลเอนต์หรือปลายทางไคลเอนต์ในเครือข่าย * {@code Connection} เมื่อเชื่อมต่อแล้ว จะสามารถแลกเปลี่ยนข้อมูลกับบุคคลอื่นหรือฝ่ายอื่นได้ ขึ้นอยู่กับ บนเซิร์ฟเวอร์ * การนำไปใช้ *

* คลาสนี้เป็น threadsafe * * @version 1.0 * @see Server * @see Client */ การเชื่อมต่อคลาสสาธารณะใช้ Runnable { ซ็อกเก็ตซ็อกเก็ตส่วนตัว; ส่วนตัว DataOutputStream ออก; DataInputStream ส่วนตัวใน; เธรดเธรดส่วนตัว วัตถุสุดท้ายส่วนตัว writeLock = วัตถุใหม่ (); วัตถุสุดท้ายส่วนตัว readLock = วัตถุใหม่ (); /** * สร้าง {@code Connection} โดยใช้สตรีมของ {@link Socket} ที่ระบุ * * @param socket Socket เพื่อดึงกระแสข้อมูล*/ การเชื่อมต่อสาธารณะ (ซ็อกเก็ตซ็อกเก็ต) พ่น NetworkException { ถ้า (socket == null) { โยน IllegalArgumentException ใหม่ ("null socket"); } this.socket = ซ็อกเก็ต; ลอง { out = ใหม่ DataOutputStream(socket.getOutputStream()); } catch (IOException e) { โยน NetworkException ใหม่ ("ไม่สามารถเข้าถึงสตรีมเอาต์พุตได้", e); } ลอง { ใน = ใหม่ DataInputStream(socket.getInputStream()); } catch (IOException e) { โยน NetworkException ใหม่ ("ไม่สามารถเข้าถึงสตรีมอินพุตได้", e); } เธรด = เธรดใหม่ (นี้); thread.start(); } /** * อ่านข้อความในขณะที่เชื่อมต่อกับอีกฝ่ายหนึ่งยังมีชีวิตอยู่ */ @Override public void run() { while (!socket.isClosed()) { ลอง { int identifier; ไบต์ ไบต์; ซิงโครไนซ์ (readLock) { ตัวระบุ = in.readInt (); ความยาว int = in.readInt(); ถ้า (ความยาว > 0) { ไบต์ = ไบต์ใหม่ [ความยาว]; in.readFully(ไบต์, 0, ไบต์.ความยาว); } อื่น ๆ { ดำเนินการต่อ; } } สวิตช์ (ตัวระบุ) { case Identifier. INTERNAL: คำสั่ง String = สตริงใหม่ (ไบต์); if (command.equals ("ตัดการเชื่อมต่อ")) { if (!socket.isClosed ()) { System.out.println ("รับแพ็คเก็ตการตัดการเชื่อมต่อ"); ลอง { ปิด (); } จับ (NetworkException จ) { กลับ; } } } หยุดพัก; case Identifier. TEXT: System.out.println("ข้อความที่ได้รับ: " + สตริงใหม่ (ไบต์)); หยุดพัก; ค่าเริ่มต้น: System.out.println("ได้รับข้อมูลที่ไม่รู้จัก"); } } จับ (SocketException e) { if (!e.getMessage().equals("Socket closed")) { e.printStackTrace(); } } จับ (IOException จ) { e.printStackTrace (); } } } /** * ส่งข้อมูลไปยังบุคคลอื่น * * @param data data ที่จะส่ง * @throws NetworkException หากการเขียนไปยังเอาต์พุตสตรีมล้มเหลว * @throws IllegalStateException หากพยายามเขียนข้อมูลเมื่อปิดการเชื่อมต่อ * @throws IllegalArgumentException หากข้อมูลที่ส่งเป็นโมฆะ * @throws UnsupportedOperationException หากพยายามส่งประเภทข้อมูลที่ไม่รองรับ */ การส่งโมฆะสาธารณะ (ข้อมูลวัตถุ) พ่น NetworkException { ถ้า (socket.isClosed ()) { โยน IllegalStateException ใหม่ ("ไม่ได้ส่งข้อมูล การเชื่อมต่อถูกปิด"); } if (data == null) { โยน IllegalArgumentException ใหม่ ("null data"); } ตัวระบุ int; ไบต์ ไบต์; if (ข้อมูลเช่นสตริง) { identifier = Identifier. TEXT; ไบต์ = ((สตริง) data).getBytes(); } อื่น { โยน UnsupportedOperationException ใหม่ ("ประเภทข้อมูลที่ไม่รองรับ: " + data.getClass ()); } ลอง { ซิงโครไนซ์ (writeLock) { out.writeInt (ตัวระบุ); out.writeInt(ไบต์.ความยาว); out.write(ไบต์); out.flush(); } } catch (IOException e) { โยน NetworkException ใหม่ ("ไม่สามารถส่งข้อมูลได้", e); } } /** * ส่งข้อความยกเลิกการเชื่อมต่อไปยังอีกฝ่าย และปิดการเชื่อมต่อ */ ปิดโมฆะสาธารณะ () พ่น NetworkException { ถ้า (socket.isClosed ()) { โยน IllegalStateException ใหม่ ("การเชื่อมต่อถูกปิดแล้ว"); } ลอง { byte message = "disconnect".getBytes(); ซิงโครไนซ์ (writeLock) { out.writeInt (Identifier. INTERNAL); out.writeInt(ข้อความ.ความยาว); out.write(ข้อความ); out.flush(); } } catch (IOException e) { System.out.println ("ไม่สามารถส่งข้อความตัดการเชื่อมต่อได้"); } ลอง { ซิงโครไนซ์ (writeLock) { out.close(); } } catch (IOException e) { โยน NetworkException ใหม่ ("เกิดข้อผิดพลาดขณะปิดการเชื่อมต่อ", e); } ในที่สุด { thread.interrupt(); } } /** * ส่งคืนว่าการเชื่อมต่อกับอีกฝ่ายหนึ่งยังมีชีวิตอยู่หรือไม่ * * @return True หากการเชื่อมต่อยังมีชีวิตอยู่ เท็จมิฉะนั้น */ isConnected บูลีนสาธารณะ () { return !socket.isClosed (); } }

Identifier.java

/** * คลาส {@code Identifier} มีค่าคงที่ที่ใช้โดย {@link Connection} สำหรับการทำให้เป็นอนุกรมและดีซีเรียลไลซ์ข้อมูล * ที่ส่งผ่านเครือข่าย * * @version 1.0 * @see Connection */ ตัวระบุคลาสสุดท้ายสาธารณะ { /** * ตัวระบุสำหรับข้อความภายใน */ สาธารณะ คงที่ สุดท้าย int ภายใน = 1; /** * ตัวระบุสำหรับข้อความ */ สาธารณะคงที่สุดท้าย int TEXT = 2; }

NetworkException.java

/** * คลาส {@code NetworkException} ระบุข้อผิดพลาดที่เกี่ยวข้องกับเครือข่าย */ คลาสสาธารณะ NetworkException ขยายข้อยกเว้น { /** * สร้าง {@code NetworkException} โดยมี {@code null} เป็นข้อความ */ public NetworkException() { } /** * สร้าง {@code NetworkException} พร้อมข้อความที่ระบุ * * @param message ข้อความอธิบายข้อผิดพลาด */ public NetworkException (ข้อความสตริง) { super (ข้อความ); } /** * สร้าง {@code NetworkException} ด้วยข้อความและสาเหตุที่ระบุ * * @param message ข้อความอธิบายข้อผิดพลาด * @param ทำให้เกิดข้อผิดพลาด */ public NetworkException (ข้อความสตริง, สาเหตุ Throwable) { super (ข้อความ, สาเหตุ); } /** * สร้าง {@code NetworkException} ด้วยสาเหตุที่ระบุ * * @param ทำให้เกิดข้อผิดพลาด */ public NetworkException (สาเหตุที่สามารถทิ้งได้) { super(cause); } }

การใช้Example.java

/** * คลาส {@code UsageExample} แสดงการใช้งานของ {@link Server} และ {@link Client} ตัวอย่างนี้ใช้ * {@link Thread#sleep(long)} เพื่อให้แน่ใจว่าทุกเซ็กเมนต์ถูกดำเนินการ เนื่องจากการเริ่มต้นและปิดอย่างรวดเร็วทำให้บางเซ็กเมนต์ * ไม่ดำเนินการ * * @version 1.0 * @see Server * @see Client */ คลาสสาธารณะ UsageExample { โมฆะสาธารณะหลัก (สตริง args) พ่นข้อยกเว้น { โฮสต์สตริง = "localhost"; พอร์ต int = 10430; เซิร์ฟเวอร์เซิร์ฟเวอร์ = เซิร์ฟเวอร์ใหม่ (โฮสต์ พอร์ต); ลูกค้าไคลเอนต์ = ลูกค้าใหม่ (โฮสต์ พอร์ต); เธรด สลีป (100L); client.send("สวัสดี"); server.broadcast("เฮ้ ไอ้หนุ่ม!"); เธรด สลีป (100L); server.disconnect(server.getConnections()[0]); เซิร์ฟเวอร์ // หรือ client.close() เพื่อยกเลิกการเชื่อมต่อจาก server-side server.close(); } }

แนะนำ: