บทความนี้จะอธิบายเกี่ยวกับแอปพลิเคชันไคลเอนต์ฝั่งเซิร์ฟเวอร์อย่างง่ายของการเขียนโปรแกรมเครือข่าย Java แบ่งปันกับทุกคนสำหรับการอ้างอิงของคุณ รายละเอียดมีดังนี้:
ใน Java เราใช้ java.net.Socket และคลาสที่เกี่ยวข้องเพื่อทำหน้าที่ที่เกี่ยวข้องกับเครือข่ายให้สมบูรณ์ คลาส Socket นั้นเรียบง่ายและใช้งานง่ายมากเพราะเทคโนโลยี Java ซ่อนกระบวนการที่ซับซ้อนในการสร้างการเชื่อมต่อเครือข่ายและการส่งข้อมูลผ่านการเชื่อมต่อ สิ่งที่กล่าวด้านล่างนี้ใช้ได้กับโปรโตคอล TCP เท่านั้น
1. เชื่อมต่อกับเซิร์ฟเวอร์
เราสามารถใช้ Constructor ของคลาส Socket เพื่อเปิด socket ได้ เช่น
ซ็อกเก็ต sk = ซ็อกเก็ตใหม่ ("210.0.235.14",13);
ในจำนวนนั้น 210.0.235.14 เป็นออบเจ็กต์สตริงทศนิยมแบบประ ซึ่งแสดงถึงที่อยู่ IP (หรือชื่อโฮสต์) ของโฮสต์ปลายทาง และ 13 แสดงถึงพอร์ตที่กำหนด 13 เพื่อเชื่อมต่อกับโฮสต์ปลายทาง 210.0.235.14 นี่คือเซิร์ฟเวอร์กำหนดเวลาที่ตั้งอยู่ในฮ่องกง พอร์ตเริ่มต้นของเซิร์ฟเวอร์กำหนดเวลาโดยทั่วไปคือ 13
โปรดทราบว่าโปรแกรมจะบล็อกจนกว่าจะเชื่อมต่อกับเซิร์ฟเวอร์ได้สำเร็จ
ถัดไป คุณสามารถใช้เมธอด getInputStream() ของคลาส Socket เพื่อรับออบเจ็กต์ InputStream คุณสามารถรับข้อมูลที่โฮสต์เป้าหมายส่งถึงเรา:
InputStream inStream = sk.getInputStream();
ในทำนองเดียวกัน หากต้องการส่งข้อมูลไปยังโฮสต์เป้าหมาย คุณสามารถเรียกใช้เมธอด getOutputStream() เพื่อรับออบเจ็กต์สตรีมเอาต์พุตได้
ฟังก์ชันตัวอย่างต่อไปนี้คือการเชื่อมต่อกับเซิร์ฟเวอร์กำหนดเวลาและพิมพ์ข้อมูลที่ส่งคืนไปยังเอาต์พุตมาตรฐาน:
ลอง { Socket sk = new Socket("210.0.235.14",13); sk.setSoTimeout(3000); InputStream inStream = sk.getInputStream(); // รับออบเจ็กต์สตรีมอินพุต sc = new Scanner(inStream); / พิมพ์ข้อมูลไปยังคอนโซล while(sc.hasNextLine()) { String str = sc.nextLine(); System.out.println("Output : " + str); } sk.close(); } catch(SocketTimeoutException e) // ข้อยกเว้นการหมดเวลา { System.out.println("หมดเวลา!"); ) { e.printStackTrace( }
เมธอด setSoTimeout() ในโค้ดสามารถตั้งค่าการหมดเวลาได้ กล่าวคือ หากการดำเนินการอ่านและเขียนไม่เสร็จสมบูรณ์หลังจากเวลาที่กำหนด SocketTimeoutException จะถูกส่งออกไป และการเชื่อมต่อสามารถปิดได้โดยการตรวจจับข้อยกเว้นนี้
นอกจากนี้ยังมีปัญหาการหมดเวลาที่ต้องแก้ไข ซึ่งเป็นตัวสร้างของคลาส Socket
ซ็อกเก็ตใหม่ (โฮสต์, พอร์ต);
มันจะบล็อกอย่างไม่มีกำหนดจนกว่าการเชื่อมต่อกับโฮสต์เป้าหมายจะสำเร็จ นี่ไม่ใช่สิ่งที่เราต้องการอย่างแน่นอน เราสามารถแก้ไขปัญหานี้ได้โดยการโทร:
Socket sk = new Socker();sk.connect(new InetSocketAddress(host,port),2000);//ตั้งค่าการหมดเวลาเป็น 2 วินาที
2. รับที่อยู่โฮสต์
เมธอดคงที่ getByName(ชื่อโฮสต์) ของคลาส InetAddress สามารถส่งคืนอ็อบเจ็กต์ InetAddress ที่แสดงที่อยู่โฮสต์ได้ อ็อบเจ็กต์นี้ล้อมรอบลำดับ 4 ไบต์ ซึ่งเป็นที่อยู่ IP ของโฮสต์ จากนั้นเรียกใช้เมธอด getHostAddress() เพื่อส่งคืนอ็อบเจ็กต์ String ที่แสดงถึงที่อยู่ IP
ชื่อโฮสต์บางชื่อที่มีปริมาณการรับส่งข้อมูลสูงมักจะสอดคล้องกับที่อยู่ IP หลายแห่งเพื่อให้เกิดความสมดุลในการโหลด เราสามารถรับที่อยู่โฮสต์ทั้งหมดได้โดยการเรียกเมธอด getAllByName() ซึ่งจะส่งคืนอาร์เรย์ของอ็อบเจ็กต์ InetAddress
ต่อไปนี้เป็นโปรแกรมขนาดเล็กธรรมดา ฟังก์ชันคือพิมพ์ที่อยู่ IP ในเครื่องหากไม่มีการตั้งค่าพารามิเตอร์บนบรรทัดคำสั่ง หากระบุชื่อโฮสต์ ที่อยู่ IP ทั้งหมดของโฮสต์จะถูกพิมพ์ออกมา:
แพ็คเกจ cls; นำเข้า java.net.*; คลาสสาธารณะ ShowIP { โมฆะสาธารณะหลัก (สตริง [] args) { ลอง { ถ้า (args.length > 0) { สตริงชื่อโฮสต์ = args [0]; ] addr = InetAddress.getAllByName(hostName); // รับที่อยู่ทั้งหมดของโฮสต์ // พิมพ์เอาต์พุตไปยังคอนโซลสำหรับ (ที่อยู่ InetAddress : addr) { System.out.println(address.getHostAddress()); } } else { System.out.println(InetAddress.getLocalHost().getHostAddress() } } catch(ข้อยกเว้น e) { e.printStackTrace() } }
3. โปรแกรมฝั่งเซิร์ฟเวอร์
แอปพลิเคชันฝั่งเซิร์ฟเวอร์ใช้คลาส ServerSocket เพื่อสร้างซ็อกเก็ตและผูกเข้ากับพอร์ตภายในเครื่อง เช่น
ถุงเท้า ServerSocket = ServerSocker ใหม่ (8000);
เมธอด sock.accept() อนุญาตให้โปรแกรมรอการเชื่อมต่ออย่างต่อเนื่อง วิธีนี้จะส่งคืนออบเจ็กต์ Socket ที่แสดงการเชื่อมต่อใหม่เมื่อมีการเชื่อมต่อเท่านั้น กล่าวคือ วิธีนี้จะบล็อก
โดยทั่วไปจำเป็นต้องเปิดเธรดใหม่สำหรับแต่ละการเชื่อมต่อเพื่อให้บริการ
ต่อไปนี้เป็นตัวอย่างที่สมบูรณ์ เซิร์ฟเวอร์รอการเชื่อมต่อที่พอร์ต 8400 เมื่อใดก็ตามที่มีการเชื่อมต่อมาถึง เธรดใหม่จะถูกเปิดเพื่อให้บริการ และข้อมูลการเชื่อมต่อจะถูกเขียนลงในไฟล์บันทึก:
แพ็คเกจ cls; import java.io.*; import java.util.*; import java.util.*; //ServerSocket servSocket = ServerSocket ใหม่ (8000); ServerSocket servSocket = ServerSocket ใหม่ (8400); ในขณะที่ (จริง) { ไคลเอนต์ซ็อกเก็ต = servSocket.accept(); วันที่เวลา = วันที่ใหม่ (); String prompt = time.toString() + ":th" + amount + "user" + client.getInetAddress ( ).getHostAddress() + "Connected/n"; System.out.print(prompt); //ส่งออกข้อมูลบนคอนโซล ServerDemo.writeLog(prompt); //เขียนไปที่ไฟล์//เริ่มเธรดใหม่ th = เธรดใหม่ (servThread ใหม่ (ไคลเอนต์, จำนวน)); th.start (); } } catch (ข้อยกเว้น e) { e.printStackTrace (); เขียนลงในไฟล์บันทึก public static void writeLog(String str) { File logFile = new File("server-log.txt"); ลอง { FileWriter out = new FileWriter(logFile,true); out.append(str); out.close(); } catch(ข้อยกเว้น e) { e.printStackTrace(); ไคลเอนต์ซ็อกเก็ต int ix; ServThread สาธารณะ (Socket soc, int ix) { ลูกค้า = soc; this.ix = ix; } { ลอง { InputStream inStream = client.getInputStream(); OutputStream outStream = client.getOutputStream(); Scanner recv = new Scanner(inStream); PrintWriter send = new PrintWriter(outStream,true); ไม่กี่คำ! [ป้อน 'บาย' เพื่อปิดการเชื่อมต่อ]"); while(recv.hasNextLine()) { String str = recv.nextLine(); if(str.equals("bye")) { send.println("แล้วพบกันใหม่) ภายหลัง ~ ^-^"); break; } send.println("นี่คือโปรแกรมทดสอบ แต่ยังไม่มีฟังก์ชัน"); } วันที่เวลา = วันที่ใหม่(); String prompt = time.toString() + ": user" + ix + "th" + client.getInetAddress().getHostAddress() + "Disconnected/n"; System.out.print(พร้อมท์); ServerDemo.writeLog( พร้อมท์); /เขียนไปยังไฟล์ client.close(); } catch(ข้อยกเว้น e) { e.printStackTrace();
โปรแกรมนี้ถูกวางไว้บนเซิร์ฟเวอร์ คุณสามารถใช้คำสั่ง telnet youthol.tk 8400 เพื่อสัมผัสกับผลลัพธ์การทำงานของโปรแกรมนี้
ฉันหวังว่าบทความนี้จะเป็นประโยชน์กับการเขียนโปรแกรม Java ของทุกคน