วิธีที่แนะนำในการรับชื่อโฮสต์ใน Java


274

ข้อใดต่อไปนี้เป็นวิธีที่ดีที่สุดและพกพาได้มากที่สุดในการรับชื่อโฮสต์ของคอมพิวเตอร์ปัจจุบันใน Java

Runtime.getRuntime().exec("hostname")

VS

InetAddress.getLocalHost().getHostName()


กองเทคโนโลยีนี้คืออะไร?
Tom redfern

ฉันคิดว่าชื่อที่ได้รับการสนับสนุนจริงเพียงชื่อเดียว (uts_name) มาจาก RMI / JMX VMID แต่นี่เป็นการใช้งานเฉพาะ
eckes

คำตอบ:


336

พูดอย่างเคร่งครัด - คุณไม่มีทางเลือก แต่เรียกอย่างใดอย่างหนึ่งhostname(1)หรือ - บน gethostname(2)Unix นี่คือชื่อคอมพิวเตอร์ของคุณ ความพยายามใด ๆ ในการระบุชื่อโฮสต์ตามที่อยู่ IP เช่นนี้

InetAddress.getLocalHost().getHostName()

ถูกผูกไว้กับความล้มเหลวในบางสถานการณ์:

  • ที่อยู่ IP อาจไม่ได้รับการแก้ไขในชื่อใด ๆ การตั้งค่า DNS ไม่ถูกต้องการตั้งค่าระบบไม่ดีหรือการตั้งค่าผู้ให้บริการที่ไม่ดีอาจเป็นสาเหตุของสิ่งนี้
  • ชื่อใน DNS สามารถมีชื่อแทนจำนวนมากที่เรียกว่า CNAME สามารถแก้ไขได้ในทิศทางเดียวเท่านั้นชื่อ: ที่อยู่ ทิศทางกลับกันไม่ชัดเจน ชื่อ "ทางการ" อันไหน
  • โฮสต์สามารถมีที่อยู่ IP ที่แตกต่างกันและแต่ละที่อยู่สามารถมีชื่อแตกต่างกันมากมาย สองกรณีที่พบบ่อยคือ: พอร์ตอีเธอร์เน็ตหนึ่งตัวมีที่อยู่ IP "แบบลอจิคัล" หลายตัวหรือคอมพิวเตอร์มีพอร์ตอีเธอร์เน็ตหลายพอร์ต สามารถกำหนดค่าได้ว่าจะแบ่งปัน IP หรือมี IP ที่แตกต่างกัน สิ่งนี้เรียกว่า "multihomed"
  • ชื่อเดียวใน DNS สามารถแก้ไขได้หลายที่อยู่ IP และไม่ใช่ที่อยู่ทั้งหมดนั้นจะต้องอยู่ในคอมพิวเตอร์เครื่องเดียวกัน! (Usecase: รูปแบบการโหลดบาลานซ์ที่เรียบง่าย)
  • อย่าแม้แต่จะเริ่มพูดถึงที่อยู่ IP แบบไดนามิก

อย่าสับสนชื่อของที่อยู่ IP กับชื่อของโฮสต์ (ชื่อโฮสต์) คำอุปมาอาจทำให้ชัดเจน:

มีเมืองใหญ่ (เซิร์ฟเวอร์) เรียกว่า "ลอนดอน" ข้างในกำแพงเมืองมีเรื่องมากมายเกิดขึ้น เมืองนี้มีหลายประตู (ที่อยู่ IP) แต่ละประตูมีชื่อ ("North Gate", "River Gate", "Southampton Gate" ... ) แต่ชื่อของประตูไม่ใช่ชื่อของเมือง นอกจากนี้คุณไม่สามารถอนุมานชื่อของเมืองโดยใช้ชื่อของประตู - "North Gate" จะจับครึ่งหนึ่งของเมืองใหญ่และไม่ใช่แค่เมืองเดียว อย่างไรก็ตาม - คนแปลกหน้า (แพ็คเก็ต IP) เดินไปตามแม่น้ำและถามคนท้องถิ่น: "ฉันมีที่อยู่แปลก ๆ : 'ริเวอร์เกตซ้ายสองบ้านหลังที่สาม' คุณช่วยฉันได้ไหม" คนในพื้นที่พูดว่า: "แน่นอนคุณอยู่บนถนนที่ถูกต้องเพียงแค่เดินหน้าต่อไปและคุณจะไปถึงจุดหมายภายในครึ่งชั่วโมง"

นี่แสดงให้เห็นว่าฉันคิดว่าสวยมาก

ข่าวดีก็คือ: ชื่อโฮสต์จริงมักไม่จำเป็น ในกรณีส่วนใหญ่ชื่อใด ๆ ที่แก้ไขเป็นที่อยู่ IP ในโฮสต์นี้จะทำ (คนแปลกหน้าอาจเข้ามาในเมืองโดย Northgate แต่ชาวบ้านที่เป็นประโยชน์แปลส่วน "2nd left")

หากกรณีที่มุมที่เหลือคุณต้องใช้ที่ชัดเจนแหล่งที่มาของการตั้งค่าการกำหนดค่านี้ - gethostname(2)ซึ่งเป็นฟังก์ชั่นซี hostnameฟังก์ชั่นที่ยังถูกเรียกโดยโปรแกรม


9
ไม่ใช่คำตอบที่ฉันหวังไว้ แต่ตอนนี้ฉันรู้วิธีถามคำถามที่ดีกว่านี้ขอบคุณ
แซม Hasler


4
นั่นเป็นข้อ จำกัด ที่ดีที่ซอฟต์แวร์ใด ๆ (ไม่ใช่แค่โปรแกรม Java) มีการกำหนดชื่อโฮสต์ในโลก อย่างไรก็ตามโปรดทราบว่า getHostName มีการใช้งานในแง่ของระบบปฏิบัติการพื้นฐานน่าจะเป็นเช่นเดียวกับชื่อโฮสต์ / gethostname บนระบบ "ปกติ" InetAddress.getLocalHost (). getHostName () เทียบเท่ากับการเรียกชื่อโฮสต์ / gethostname ดังนั้นคุณจึงไม่สามารถพูดได้ว่าวิธีหนึ่งล้มเหลวในลักษณะที่อีกฝ่ายไม่ได้ทำ
Peter Cardona

System.err.println (Runtime.getRuntime () exec ( "ชื่อโฮสต์").); ให้สิ่งนี้กับฉัน: java.lang.UNIXProcess@6eb2384f
user152468

5
การใช้ InetAddress.getLocalHost (). getHostName () เป็นสิ่งที่กำหนดขึ้นจริง ๆ :) ถ้าคุณทำตามซอร์สโค้ดมันจะเรียกใช้ gethostname () บน Windows และ getaddrinfo () ในระบบ Unixy ผลลัพธ์จะเหมือนกับการใช้คำสั่งชื่อโฮสต์ OS ของคุณ ตอนนี้ชื่อโฮสต์อาจให้คำตอบที่คุณไม่ต้องการใช้นั่นเป็นไปได้ด้วยเหตุผลหลายประการ โดยทั่วไปซอฟต์แวร์ควรได้รับชื่อโฮสต์จากผู้ใช้ในไฟล์กำหนดค่าด้วยวิธีนี้จะเป็นชื่อโฮสต์ที่ถูกต้องเสมอ คุณสามารถใช้ InetAddress.getLocalhost (). getHostName () เป็นค่าเริ่มต้นหากผู้ใช้ไม่ได้ให้ค่า
เกร็ก

93

InetAddress.getLocalHost().getHostName() เป็นวิธีพกพามากขึ้น

exec("hostname")จริงเรียกออกไปยังระบบปฏิบัติการเพื่อรันhostnameคำสั่ง

นี่คือคำตอบที่เกี่ยวข้องอื่น ๆ สองสามข้อเกี่ยวกับ SO:

แก้ไข:คุณควรดูคำตอบของ AHหรือคำตอบของArnout Engelenสำหรับรายละเอียดเกี่ยวกับสาเหตุที่อาจไม่ทำงานตามที่คาดไว้ทั้งนี้ขึ้นอยู่กับสถานการณ์ของคุณ ในฐานะที่เป็นคำตอบสำหรับคนที่ขอพกพาเป็นพิเศษฉันยังคิดว่าใช้ได้getHostName()แต่พวกเขานำคะแนนที่ดีมาพิจารณา


12
การเรียกใช้ getHostName () ส่งผลให้เกิดข้อผิดพลาดบางครั้ง เช่นนี่คือสิ่งที่ฉันได้รับในอินสแตนซ์ Amazon EC2 AMI Linux: java.net.UnknownHostException: ชื่อหรือบริการที่ไม่รู้จัก java.net.InetAddress.getLocalHost (InetAddress.java:1438)
Marquez

1
นอกจากนี้InetAddress.getLocalHost()ในบางกรณีจะส่งคืนอุปกรณ์ลูปแบ็ค ในกรณีนั้นgetHostName()คืนค่า "localhost" ซึ่งไม่มีประโยชน์มาก
olenz

53

ดังที่คนอื่น ๆ จดไว้การรับชื่อโฮสต์ตามการแก้ไข DNS นั้นไม่น่าเชื่อถือ

เนื่องจากคำถามนี้ยังมีความเกี่ยวข้องในปี 2561ฉันต้องการแบ่งปันโซลูชันเครือข่ายของฉันกับคุณโดยมีการทดสอบบางอย่างทำงานในระบบที่แตกต่างกัน

รหัสต่อไปนี้พยายามทำสิ่งต่อไปนี้:

  • บน Windows

    1. อ่านตัวแปรสภาพแวดล้อมผ่านCOMPUTERNAMESystem.getenv()

    2. ดำเนินการhostname.exeและอ่านการตอบสนอง

  • บน Linux

    1. อ่านHOSTNAMEตัวแปรสภาพแวดล้อมผ่านSystem.getenv()

    2. ดำเนินการhostnameและอ่านการตอบสนอง

    3. อ่าน/etc/hostname(เพื่อทำสิ่งนี้ฉันกำลังดำเนินการcatเนื่องจากข้อมูลโค้ดมีรหัสที่จะดำเนินการและอ่านอยู่แล้วการอ่านไฟล์จะดีกว่า)

รหัส:

public static void main(String[] args) throws IOException {
    String os = System.getProperty("os.name").toLowerCase();

    if (os.contains("win")) {
        System.out.println("Windows computer name through env:\"" + System.getenv("COMPUTERNAME") + "\"");
        System.out.println("Windows computer name through exec:\"" + execReadToString("hostname") + "\"");
    } else if (os.contains("nix") || os.contains("nux") || os.contains("mac os x")) {
        System.out.println("Unix-like computer name through env:\"" + System.getenv("HOSTNAME") + "\"");
        System.out.println("Unix-like computer name through exec:\"" + execReadToString("hostname") + "\"");
        System.out.println("Unix-like computer name through /etc/hostname:\"" + execReadToString("cat /etc/hostname") + "\"");
    }
}

public static String execReadToString(String execCommand) throws IOException {
    try (Scanner s = new Scanner(Runtime.getRuntime().exec(execCommand).getInputStream()).useDelimiter("\\A")) {
        return s.hasNext() ? s.next() : "";
    }
}

ผลลัพธ์สำหรับระบบปฏิบัติการที่แตกต่างกัน:

macOS 10.13.2

Unix-like computer name through env:"null"
Unix-like computer name through exec:"machinename
"
Unix-like computer name through /etc/hostname:""

OpenSuse 13.1

Unix-like computer name through env:"machinename"
Unix-like computer name through exec:"machinename
"
Unix-like computer name through /etc/hostname:""

Ubuntu 14.04 LTS อันนี้ค่อนข้างแปลกตั้งแต่echo $HOSTNAMEคืนชื่อโฮสต์ที่ถูกต้อง แต่System.getenv("HOSTNAME")ไม่:

Unix-like computer name through env:"null"
Unix-like computer name through exec:"machinename
"
Unix-like computer name through /etc/hostname:"machinename
"

แก้ไข:ตามlegolas108 , System.getenv("HOSTNAME")ทำงานบน Ubuntu 14.04 ถ้าคุณทำงานexport HOSTNAMEก่อนที่จะดำเนินรหัส Java

วินโดว 7

Windows computer name through env:"MACHINENAME"
Windows computer name through exec:"machinename
"

Windows 10

Windows computer name through env:"MACHINENAME"
Windows computer name through exec:"machinename
"

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


3
หากคุณexport HOSTNAMEก่อนที่จะใช้รหัส Java บน Ubuntu 14.04 LTS System.getenv("HOSTNAME")ก็ยังกลับโดย
legolas108

คุณต้องexport HOSTNAMEใช้ Java อย่างชัดเจนหรือไม่? ฉันคิดว่ามันควรเป็นค่าเริ่มต้น env var เช่น PATH
David

2
ใช่นี่เป็นหนึ่งในข้อบกพร่องของจาวาที่จะไม่ถูกแก้ไขด้วยเหตุผลทางศาสนา ที่เกี่ยวข้องจะสามารถตั้งชื่อกระบวนการ ข้อบกพร่องเข้าสู่ระบบเกือบ 20 ปีที่ผ่านมา
Tuntable

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

1
@Charlie \Aคั่นเป็นเพียงสับสำหรับอ่าน InputStream Scannerทั้งหมดใช้
มอลต์

24

InetAddress.getLocalHost().getHostName() ดีกว่า (ตามที่นิคอธิบาย) แต่ก็ยังไม่ค่อยดีเท่าไหร่

หนึ่งโฮสต์สามารถเป็นที่รู้จักภายใต้ชื่อโฮสต์ที่แตกต่างกัน โดยปกติคุณจะมองหาชื่อโฮสต์ที่โฮสต์ของคุณมีในบริบทที่ระบุ

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

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


18

แม้ว่าหัวข้อนี้จะได้รับคำตอบแล้วยังมีอีกหลายสิ่งที่จะพูด

ก่อนอื่น: เห็นได้ชัดว่าเราต้องการคำจำกัดความบางอย่างที่นี่ The InetAddress.getLocalHost().getHostName()ให้ชื่อโฮสต์ที่เห็นจากมุมมองเครือข่ายเท่าที่เห็นจากมุมมองของเครือข่ายปัญหาเกี่ยวกับวิธีการนี้ได้รับการบันทึกไว้เป็นอย่างดีในคำตอบอื่น ๆ : มันมักจะต้องมีการค้นหา DNS มันไม่ชัดเจนถ้าโฮสต์มีอินเตอร์เฟซเครือข่ายหลายตัวและบางครั้งก็ล้มเหลว

แต่ในระบบปฏิบัติการใด ๆ ก็มีอีกชื่อหนึ่งเช่นกัน ชื่อของโฮสต์ที่ได้รับการกำหนดตั้งแต่ต้นในกระบวนการบู๊ตนานก่อนที่เครือข่ายจะเริ่มต้นได้ ของ Windows หมายถึงนี้เป็นcomputernameลินุกซ์เรียกมันว่าเคอร์เนลชื่อโฮสต์และ Solaris ใช้คำว่าnodename ฉันชอบคำว่าcomputernameดีที่สุดดังนั้นฉันจะใช้คำนั้นต่อจากนี้ไป

การค้นหาชื่อคอมพิวเตอร์

  • บน Linux / Unix ชื่อคอมพิวเตอร์คือสิ่งที่คุณได้รับจากฟังก์ชัน C gethostname()หรือhostnameคำสั่งจากเชลล์หรือHOSTNAMEตัวแปรสภาพแวดล้อมในเชลล์เหมือน Bash

  • ใน Windows computername คือสิ่งที่คุณได้รับจากตัวแปรสภาพแวดล้อมCOMPUTERNAMEหรือGetComputerNameฟังก์ชันWin32

Java ไม่มีวิธีรับสิ่งที่ฉันกำหนดเป็น 'ชื่อคอมพิวเตอร์' ตรวจสอบว่ามีการแก้ไขปัญหาที่อธิบายไว้ในคำตอบอื่น ๆ เช่นสำหรับ Windows โทรSystem.getenv("COMPUTERNAME")แต่ใน Unix / Linux ไม่มีวิธีแก้ปัญหาที่ดีโดยไม่ต้อง resorting JNI / JNA Runtime.exec()หรือ หากคุณไม่สนใจโซลูชัน JNI / JNA ก็มีgethostname4jซึ่งตายง่ายและใช้งานง่ายมาก

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

ตัวอย่างลินุกซ์

บนระบบที่สร้างขึ้นใหม่ซึ่งโฮสต์ระหว่างการติดตั้งได้รับการตั้งชื่อว่า 'chicago' ตอนนี้เราเปลี่ยนชื่อโฮสต์เคอร์เนล:

$ hostnamectl --static set-hostname dallas

ตอนนี้ชื่อโฮสต์เคอร์เนลคือ 'dallas' ดังที่เห็นได้จากคำสั่งชื่อโฮสต์:

$ hostname
dallas

แต่เรายังมี

$ cat /etc/hosts
127.0.0.1   localhost
127.0.0.1   chicago

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

ตอนนี้ลองดำเนินการInetAddress.getLocalHost().getHostName() แล้วมันจะโยน java.net.UnknownHostException คุณติดอยู่โดยทั่วไป ไม่มีวิธีใดในการเรียกคืนทั้งค่า 'ดัลลัส' หรือค่า 'ชิคาโก'

ตัวอย่าง Solaris

ตัวอย่างด้านล่างใช้ Solaris 11.3

โฮสต์ได้รับการกำหนดค่าโดยเจตนาเพื่อให้ชื่อลูปแบ็ค <> ชื่อโหนด

ในคำอื่น ๆ เรามี:

$ svccfg -s system/identity:node listprop config
...
...
config/loopback             astring        chicago
config/nodename             astring        dallas

และเนื้อหาของ / etc / hosts:

:1 chicago localhost
127.0.0.1 chicago localhost loghost

และผลลัพธ์ของคำสั่ง hostname จะเป็น:

$ hostname
dallas

เช่นเดียวกับในตัวอย่างของ Linux การเรียกใช้InetAddress.getLocalHost().getHostName()จะล้มเหลว

java.net.UnknownHostException: dallas:  dallas: node name or service name not known

เช่นเดียวกับตัวอย่างของ Linux ที่คุณติดอยู่ ไม่มีวิธีใดในการเรียกคืนทั้งค่า 'ดัลลัส' หรือค่า 'ชิคาโก'

คุณจะต่อสู้กับสิ่งนี้เมื่อใด

บ่อยครั้งที่คุณจะพบว่าInetAddress.getLocalHost().getHostName()จริง ๆ แล้วจะคืนค่าซึ่งเท่ากับชื่อคอมพิวเตอร์ ดังนั้นจึงไม่มีปัญหา (ยกเว้นค่าใช้จ่ายเพิ่มเติมของการแก้ไขชื่อ)

ปัญหาเกิดขึ้นโดยทั่วไปในสภาพแวดล้อม PaaS ซึ่งมีความแตกต่างระหว่างชื่อคอมพิวเตอร์และชื่อของอินเทอร์เฟซย้อนกลับ ตัวอย่างเช่นผู้คนรายงานปัญหาใน Amazon EC2

รายงานบั๊ก / RFE

บิตของการค้นหาเผยรายงาน RFE นี้: link1 , link2 อย่างไรก็ตามการตัดสินจากความคิดเห็นในรายงานนั้นดูเหมือนว่าทีม JDK จะเข้าใจผิดเป็นส่วนใหญ่ดังนั้นจึงไม่น่าที่จะได้รับการแก้ไข

ฉันชอบการเปรียบเทียบใน RFE กับภาษาการเขียนโปรแกรมอื่น


12

ตัวแปรสภาพแวดล้อมอาจเป็นวิธีที่มีประโยชน์COMPUTERNAMEสำหรับ Windows HOSTNAMEบนเชลล์ Unix / Linux ที่ทันสมัยที่สุด

ดู: https://stackoverflow.com/a/17956000/768795

ฉันใช้วิธีเหล่านี้เป็นวิธี "เสริม" InetAddress.getLocalHost().getHostName()เนื่องจากหลาย ๆ คนชี้ให้เห็นว่าฟังก์ชั่นนั้นไม่สามารถใช้งานได้ในทุกสภาพแวดล้อม

Runtime.getRuntime().exec("hostname")เป็นอีกอาหารเสริมที่เป็นไปได้ ในขั้นตอนนี้ฉันไม่ได้ใช้มัน

import java.net.InetAddress;
import java.net.UnknownHostException;

// try InetAddress.LocalHost first;
//      NOTE -- InetAddress.getLocalHost().getHostName() will not work in certain environments.
try {
    String result = InetAddress.getLocalHost().getHostName();
    if (StringUtils.isNotEmpty( result))
        return result;
} catch (UnknownHostException e) {
    // failed;  try alternate means.
}

// try environment properties.
//      
String host = System.getenv("COMPUTERNAME");
if (host != null)
    return host;
host = System.getenv("HOSTNAME");
if (host != null)
    return host;

// undetermined.
return null;

6
StringUtils? นั่นคืออะไร?? (ฉันรู้ว่าสิ่งที่คุณหมายถึงฉันแค่คิดว่ามันเป็นกรรมที่ไม่ดีที่จะนำห้องสมุดภายนอกเพื่อจุดประสงค์เดียวนี้ .. และเหนือสิ่งอื่นใดที่ไม่ได้กล่าวถึง)
เตอร์

23
กรรมไม่ดีที่จะเขียนเช็ค "ว่าง" อย่างต่อเนื่องด้วยตนเอง โครงการจำนวนมากมีการตรวจสอบดังกล่าวด้วยตนเอง (วิธีที่คุณแนะนำ) และไม่สอดคล้องกับข้อบกพร่องที่เกิดขึ้นจำนวนมาก ใช้ห้องสมุด
Thomas W

15
ในกรณีที่ทุกคนเห็นสิ่งนี้และสับสนจริง ๆStringUtilsมันมีให้โดยโครงการ Apache คอมมอนส์ lang ขอแนะนำให้ใช้หรือสิ่งที่ชอบ
JBCP

อย่างใดSystem.getenv("HOSTNAME")ก็ออกมาเป็นโมฆะบน Mac ผ่าน Beanshell สำหรับ Java แต่PATHถูกสกัดออกมา ฉันก็สามารถทำได้echo $HOSTNAMEบน Mac ด้วยเช่นกันดูเหมือนว่า System.getenv ("HOSTNAME") ก็มีปัญหาเช่นกัน แปลก.
David

6

วิธีพกพาที่สุดในการรับชื่อโฮสต์ของคอมพิวเตอร์ปัจจุบันใน Java มีดังนี้:

import java.net.InetAddress;
import java.net.UnknownHostException;

public class getHostName {

    public static void main(String[] args) throws UnknownHostException {
        InetAddress iAddress = InetAddress.getLocalHost();
        String hostName = iAddress.getHostName();
        //To get  the Canonical host name
        String canonicalHostName = iAddress.getCanonicalHostName();

        System.out.println("HostName:" + hostName);
        System.out.println("Canonical Host Name:" + canonicalHostName);
    }
}

8
ความสะดวกในการพกพาวิธีนี้เปรียบเทียบกับวิธีการในคำถามได้อย่างไร ข้อดี / ข้อเสียคืออะไร
Marquez

4

ถ้าคุณไม่ใช้การพึ่งพาภายนอกจากศูนย์กลาง maven ฉันเขียน gethostname4j เพื่อแก้ปัญหานี้ด้วยตัวเอง มันใช้ JNA เพื่อเรียกใช้ฟังก์ชัน gethostname ของ libc (หรือรับ ComputerName บน Windows) และส่งคืนให้คุณเป็นสตริง

https://github.com/mattsheppard/gethostname4j


3
hostName == null;
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
{
    while (interfaces.hasMoreElements()) {
        NetworkInterface nic = interfaces.nextElement();
        Enumeration<InetAddress> addresses = nic.getInetAddresses();
        while (hostName == null && addresses.hasMoreElements()) {
            InetAddress address = addresses.nextElement();
            if (!address.isLoopbackAddress()) {
                hostName = address.getHostName();
            }
        }
    }
}

1
ประโยชน์ของวิธีนี้คืออะไร?
Sam Hasler

1
นี่ไม่ถูกต้อง แต่จะให้ชื่อของ NIC แรกที่ไม่ใช่อะแดปเตอร์ย้อนกลับ
Steve-o

จริงๆแล้วมันไม่ใช่ลูปแบ็คแรกที่มีชื่อโฮสต์ ... ไม่จำเป็นต้องเป็นลูปแบ็คแรก
Adam Gent

1

เพียงหนึ่งซับไลน์ ... ข้ามแพลตฟอร์ม (Windows-Linux-Unix-Mac (Unix)) [ใช้งานได้เสมอไม่จำเป็นต้องใช้ DNS]:

String hostname = new BufferedReader(
    new InputStreamReader(Runtime.getRuntime().exec("hostname").getInputStream()))
   .readLine();

คุณทำเสร็จแล้ว !!


InetAddress.getLocalHost (). getHostName () จะไม่ทำงานใน Unix?
P Satish Patro

1
ใช้งานได้ แต่ต้องมีความละเอียด dns จะเกิดอะไรขึ้นถ้าคุณเชื่อมต่อกับ wifi tethering จากโทรศัพท์ของคุณ (พูดถึงเพียงตัวอย่างเดียว) DNS จะไม่รู้จักเครื่อง localhost และมันจะไม่ทำงาน
Dan Ortega

-2

InetAddress.getLocalHost (). getHostName () เป็นวิธีที่ดีที่สุดจากทั้งสองเนื่องจากเป็นสิ่งที่ดีที่สุดในระดับนักพัฒนา


ฉันกำลังมองหาคำตอบที่เกี่ยวข้องกับโฮสต์หนึ่งรู้โดยชื่อโฮสต์หลาย
Sam Hasler

@ SamHasler สถานการณ์เฉพาะของคุณคืออะไร? ตามที่ Arnout อธิบายมีหลายวิธีขึ้นอยู่กับสิ่งที่คุณต้องการ
Nick Knowlson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.