เนื่องจากฉันต้องการสร้างการออกแบบหลักสูตรเครือข่ายคอมพิวเตอร์เครือข่ายและไม่ต้องการทำการเดินสายเครือข่ายหรือการกำหนดค่าเราเตอร์ LAN ฯลฯ ในที่สุดฉันก็ตัดสินใจใช้ซ็อกเก็ตเพื่อเขียนห้องแชท LAN ตาม Java:
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับซ็อกเก็ตและการเขียนโปรแกรมเครือข่ายโปรดดูบทความอื่น ๆ ของฉัน: การเขียนโปรแกรมที่ใช้ซ็อกเก็ต Java
โปรแกรมขึ้นอยู่กับโครงสร้าง C/S นั่นคือโหมดเซิร์ฟเวอร์ไคลเอนต์
เซิร์ฟเวอร์:
IP เริ่มต้นคือ IP ดั้งเดิม
ทั้งสองฝ่ายจำเป็นต้องกำหนดหมายเลขพอร์ตเพื่อตั้งค่าจำนวนสูงสุดของคนที่เชื่อมต่อ อินเทอร์เฟซสามารถเริ่มต้นและปิดเพื่อแสดงผู้ใช้ออนไลน์และชื่อ (หน่วยนี้ไม่ปรากฏที่นี่)
ลูกค้า:
จำเป็นต้องตั้งค่าที่อยู่ IP ของเซิร์ฟเวอร์ด้วยตนเอง (LAN)
ตั้งค่าหมายเลขพอร์ตด้วยตนเองและป้อนชื่อเพื่อเชื่อมต่อและตัดการเชื่อมต่อโปรแกรมที่ใช้งานอินเตอร์เฟสดังนี้:
เซิร์ฟเวอร์:
ลูกค้า:
ฉันจะอัปโหลดรหัสเฉพาะในตอนท้าย
มีข้อบกพร่องมากมายในซอฟต์แวร์เช่น:
ไม่มีการเพิ่มประสิทธิภาพการแยกด้วยฐานข้อมูล: ผู้ใช้ทุกคนสามารถเก็บไว้ในฐานข้อมูลและสามารถบันทึกการแชทในฐานข้อมูลได้ การเพิ่มประสิทธิภาพการแชทแบบหนึ่งต่อหนึ่งไม่ได้ถูกนำมาใช้: ยังมีข้อบกพร่องมากมายในวิธีการนิยามการแชทแบบหนึ่งต่อหนึ่ง หากคุณสนใจมันกลับมาศึกษาอย่างช้าๆ
ต่อไปนี้เป็นสามรหัสสำหรับโปรแกรม:
user.java
ผู้ใช้ระดับสาธารณะ { / *** คลาสข้อมูลผู้ใช้* ใช้เพื่อบันทึกข้อมูลส่วนบุคคลของผู้ใช้: ชื่อและ IP* / ชื่อสตริงส่วนตัว; สตริงส่วนตัว IP; ผู้ใช้สาธารณะ (ชื่อสตริง, สตริง ip) {this.name = name; this.ip = ip; } สตริงสาธารณะ getName () {ชื่อคืน; } โมฆะสาธารณะ setName (ชื่อสตริง) {this.name = name; } สตริงสาธารณะ getip () {return ip; } โมฆะสาธารณะ setip (string ip) {this.ip = ip; -Server_more.java
นำเข้า java.awt.borderlayout; นำเข้า java.awt.color; นำเข้า java.awt.gridlayout; นำเข้า java.awt.toolkit; นำเข้า java.awt.event.actionevent; นำเข้า java.awt.event.actionListener java.awt.event.windowevent; นำเข้า java.io.bufferedreader; นำเข้า java.io.ioexception; นำเข้า java.io.inputstreamreader; นำเข้า java.io.printwriter; นำเข้า Java.net.bindexception; นำเข้า Java.net.serversocket java.util.arraylist; นำเข้า java.util.stringtokenizer; นำเข้า Javax.swing.defaultlistmodel; นำเข้า Javax.swing.jbutton; นำเข้า Javax.swing.jframe; นำเข้า Javax.swing.jlabel; javax.swing.jpanel; นำเข้า Javax.swing.jscrollpane; นำเข้า Javax.swing.jsplitpane; นำเข้า Javax.swing.jtextarea; นำเข้า Javax.swing.jtextfield; นำเข้า Javax.swing.border.titledborder Private Jtextarea ContentArea; // ฟิลด์ข้อความส่วนตัว jtextfield txt_message; // ใช้เพื่อแสดงข้อมูลข้อความส่วนตัว jtextfield txt_max; // ตั้งค่าจำนวนสูงสุดของคนที่เชื่อมต่อส่วนตัว jtextfield txt_port; // ตั้งค่าหมายเลขพอร์ตส่วนตัว JButton BTN_START; // เริ่มปุ่มส่วนตัว jbutton btn_stop; // ปุ่มตัดการเชื่อมต่อส่วนตัว jbutton btn_send; // ส่งปุ่มส่วนตัว JPanel Northpanel; // North Panel ส่วนตัว JPanel Southpanel; // South Panel Private Jscrollpane Rightpanel; // left scroll bar ส่วนตัว jscrollpane leftpanel; // Right Scroll Bar Private JSplitpane Centersplit; // split line jlist userlist; // ส่วนประกอบเดี่ยวส่วนตัว defaultListModel ListModel; Serversocket ส่วนตัว Serversocket; เซิร์ฟเวอร์เซิร์ฟเวอร์ส่วนตัวเซิร์ฟเวอร์เธรด; ไคลเอนต์ ArrayList ส่วนตัว <ClientThread> ลูกค้า; บูลีนส่วนตัว iSstart = false; // วิธีการหลัก, การดำเนินการโปรแกรมรายการโมฆะคงที่สาธารณะหลัก (สตริง [] args) {new server_more (); } // Execute Message ส่งโมฆะสาธารณะส่ง () {if (! iSstart) {joptionpane.showMessageDialog (เฟรม "เซิร์ฟเวอร์ยังไม่ได้เริ่มต้นและข้อความไม่สามารถส่งได้!", "ข้อผิดพลาด", joptionpane.error_message); กลับ; } if (clients.size () == 0) {joptionpane.showMessagedialog (เฟรม, "ไม่มีผู้ใช้ออนไลน์ไม่สามารถส่งข้อความได้!", "ข้อผิดพลาด", joptionpane.error_message); กลับ; } สตริงข้อความ = txt_message.getText (). trim (); if (message == null || message.equals ("")) {joptionpane.showMessagedialog (เฟรม, "ข้อความไม่สามารถว่างเปล่า!", "ข้อผิดพลาด", joptionpane.error_message); กลับ; } sendServerMessage (ข้อความ); // ข้อความเซิร์ฟเวอร์มวล contentArea.Append ("เซิร์ฟเวอร์:" + txt_message.getText () + "/r/n"); txt_message.settext (null); } // สร้างวิธีการวาง public server_more () {frame = new JFrame ("เซิร์ฟเวอร์"); // เปลี่ยนไอคอนของ jframe: //frame.seticonimage(toolkit.getdefaulttoolkit().createImage(client.class.getResource("qq.png ")))); //frame.seticonimage(toolkit.getDefaultToolkit().createImage(Server.class.getResource("qq.png ")))); ContentArea = new JtextArea (); ContentArea.seteditable (เท็จ); ContentArea.setforeground (color.blue); txt_message = new jtextfield (); txt_max = new jtextfield ("30"); txt_port = ใหม่ jtextfield ("6666"); btn_start = new JButton ("เริ่ม"); btn_stop = new jbutton ("หยุด"); btn_send = new jbutton ("ส่ง"); btn_stop.setenabled (เท็จ); ListModel = ใหม่ defaultListModel (); userlist = new Jlist (ListModel); SOUTHPANEL = JPANEL ใหม่ (New BorderLayout ()); SouthPanel.SetBorder (ใหม่ titledBorder ("ข้อความเขียน")); Southpanel.add (txt_message, "center"); Southpanel.add (BTN_SEND, "East"); leftPanel = new JScrollpane (Userlist); leftPanel.SetBorder (ใหม่ titledBorder ("ผู้ใช้ออนไลน์")); RightPanel = new JScrollpane (ContentArea); RightPanel.SetBorder (ใหม่ titledBorder ("พื้นที่แสดงข้อความ")); CenterSplit = ใหม่ JSPlitPane (JSplitPane.horizontal_split, ซ้ายแพน, แพนขวา); CenterSplit.setDividerLocation (100); NorthPanel = new JPanel (); Northpanel.setLayout (ใหม่ gridlayout (1, 6)); NorthPanel.Add (New Jlabel ("Upper Limit")); northpanel.add (txt_max); Northpanel.add (New Jlabel ("Port")); northpanel.add (txt_port); NorthPanel.Add (BTN_START); NorthPanel.Add (BTN_STOP); NorthPanel.SetBorder (ใหม่ titledBorder ("ข้อมูลการกำหนดค่า")); frame.setLayout (New BorderLayout ()); frame.add (Northpanel, "North"); frame.add (Centersplit, "center"); Frame.add (Southpanel, "South"); frame.setsize (600, 400); //frame.setsize(toolkit.getDefaultToolkit (). getScreensize ()); // ตั้งค่าหน้าจอเต็มหน้าจอ int screen_width = toolkit.getdefaulttoolkit (). getScreensize (). ความกว้าง; int screen_height = toolkit.getdefaulttoolkit (). getScreensize (). ความสูง; frame.setLocation ((screen_width - frame.getWidth ()) / 2, (screen_height - frame.getheight ()) / 2); frame.setVisible (จริง); // เหตุการณ์เมื่อปิดเฟรมหน้าต่าง AddWindowListener (WindowAdapter ใหม่ () {โมฆะสาธารณะการปิดหน้าต่าง (WindowEvent E) {ถ้า (iSstart) {ปิดการขาย (); // ปิดเซิร์ฟเวอร์} system.exit (0); // โปรแกรมออก}}); // เหตุการณ์ txt_message.addactionListener (ใหม่ actionListener () {โมฆะสาธารณะ actionperformed (ActionEvent E) {send ();}}); // เหตุการณ์ btn_send.addactionListener (ใหม่ actionListener () {โมฆะสาธารณะ ActionPerformed (ActionEvent Arg0) {send ();}}); // เหตุการณ์ btn_start.addactionListener (ใหม่ actionListener () {โมฆะสาธารณะ actionperformed (actionEvent e) {ถ้า (iSstart) {joptionpane.ShowMessagedialog (เฟรม "อยู่ในสถานะเริ่มต้น ลอง {max = integer.parseint (txt_max.getText ()); integer.parseint (txt_port.getText ()); + "/r/n"); txt_max.setenabled (เท็จ); txt_port.setenabled (เท็จ); btn_stop.setenabled (จริง); } catch (exc Exception) {joptionpane.showMessageDialog (เฟรม, exc.getMessage (), "ข้อผิดพลาด", joptionpane.error_message); - // เหตุการณ์ btn_stop.addactionListener (ใหม่ actionListener () {โมฆะสาธารณะ actionperformed (actionEvent e) {ถ้า (! iSstart) {joptionpane.ShowMessagedialog (เฟรม "เซิร์ฟเวอร์ยังไม่จำเป็นต้องหยุด!", "ข้อผิดพลาด" btn_start.setenabled (จริง); txt_max.setenabled (จริง); JOptionPane.ShowMessAgedialOg (เฟรม, "ข้อยกเว้นเกิดขึ้นเมื่อเซิร์ฟเวอร์หยุดทำงาน!", "ข้อผิดพลาด", joptionpane.error_message);}}); } // เริ่มต้นโมฆะสาธารณะเซิร์ฟเวอร์ serverstart (int max, พอร์ต int) พ่น java.net.bindexception {ลอง {clients = new ArrayList <ClientThread> (); Serversocket = ใหม่ Serversocket (พอร์ต); ServerThread = ใหม่ ServerTHread (Serversocket, Max); Serverthread.start (); iSstart = true; } catch (bindexception e) {iSstart = false; โยน bindexception ใหม่ ("หมายเลขพอร์ตถูกครอบครองโปรดเปลี่ยนมัน!"); } catch (Exception e1) {e1.printstacktrace (); ISSTART = FALSE; โยน bindexception ใหม่ ("Start Server Exception!"); }} // ปิดเซิร์ฟเวอร์ @suppresswarnings ("การเสียสละ") โมฆะสาธารณะปิด () {ลอง {ถ้า (เซิร์ฟเวอร์ sterver! = null) serverthread.stop (); // หยุดเธรดเซิร์ฟเวอร์สำหรับ (int i = client.size ()-1; i> = 0; clients.get (i) .getWriter (). println ("ปิด"); clients.get (i) .getWriter (). flush (); // ปล่อยทรัพยากร client.get (i) .stop (); // หยุดเธรดนี้ให้บริการลูกค้าลูกค้า (i) .reader.close (); clients.get (i) .writer.close (); clients.get (i) .socket.close (); clients.remove (i); } if (serversocket! = null) {serversocket.close (); // ปิดการเชื่อมต่อด้านเซิร์ฟเวอร์} listmodel.removeAllelements (); // ล้างรายการผู้ใช้ iSstart = false; } catch (ioexception e) {e.printstacktrace (); iSstart = true; }} // ข้อความเซิร์ฟเวอร์จำนวนมากโมฆะโมฆะ sendServerMessage (ข้อความสตริง) {สำหรับ (int i = clients.size ()-1; i> = 0; i--) {clients.get (i) .getWriter () println ("เซิร์ฟเวอร์:" + ข้อความ + "(หลายส่ง)"); clients.get (i) .getWriter (). flush (); }} // เซิร์ฟเวอร์เธรดคลาสเซิร์ฟเวอร์เธรดขยายเธรด {ส่วนตัว Serversocket Serversocket; INT ส่วนตัวสูงสุด; // จำนวนผู้คน // วิธีการสร้างวิธีการของเซิร์ฟเวอร์เธรดเซิร์ฟเวอร์สาธารณะเซิร์ฟเวอร์ (Serversocket Serversocket, int max) {this.Serversocket = Serversocket; this.max = สูงสุด; } โมฆะสาธารณะเรียกใช้ () {ในขณะที่ (จริง) {// รอคอยลิงค์ไคลเอนต์ลอง {ซ็อกเก็ตซ็อกเก็ต = serversocket.accept (); if (client.size () == สูงสุด) {// ถ้าจำนวนสูงสุดของคนถึง bufferedreader r = bufferedreader ใหม่ (ใหม่ inputStreamReader (socket.getInputStream ()); PrintWriter W = ใหม่ PrintWriter (ซ็อกเก็ต. getOutputStream ()); // รับข้อมูลผู้ใช้พื้นฐานจากสตริงไคลเอนต์ inf = r.readline (); StringTokenizer st = new StringTokenizer (inf, "@"); ผู้ใช้ผู้ใช้ = ผู้ใช้ใหม่ (st.nexttoken (), st.nexttoken ()); // ข้อมูลการเชื่อมต่อความสำเร็จข้อมูลความสำเร็จ w.println ("max@server: ขออภัย" + user.getName () + user.getip () + "จำนวนคนออนไลน์บนเซิร์ฟเวอร์ถึงขีด จำกัด บนโปรดลองเชื่อมต่อในภายหลัง!"); W. Flush (); // ปล่อยทรัพยากร r.close (); w.close (); Socket.close (); ดำเนินการต่อ; } clientThread client = new ClientThread (ซ็อกเก็ต); client.start (); // เริ่มเธรดสำหรับไคลเอนต์บริการไคลเอนต์นี้ ADD (ไคลเอนต์); ListModel.AddElement (client.getUser (). getName ()); // อัปเดตรายการออนไลน์ที่มีเนื้อหา (client.getUser (). getName () + client.getUser (). getip () + "ออนไลน์!/r/n"); } catch (ioexception e) {e.printstacktrace (); }}}}} // เธรดที่ให้บริการคลาสไคลเอนต์ไคลเอนต์เธรดขยายเธรด {ซ็อกเก็ตซ็อกเก็ตส่วนตัว; ตัวอ่านบัฟเฟอร์รีดส่วนตัว; นักเขียน Private Printwriter; ผู้ใช้ส่วนตัว Public BufferedReader GetReader () {return reader; } Public PrintWriter GetWriter () {Return Writer; } ผู้ใช้สาธารณะ getUser () {return user; } // constructor ของไคลเอนต์เธรด Public ClientThread (ซ็อกเก็ตซ็อกเก็ต) {ลอง {this.socket = ซ็อกเก็ต; reader = ใหม่ bufferedReader (ใหม่ inputStreamReader (ซ็อกเก็ต. getInputStream ())); Writer = New PrintWriter (Socket.GetOutputStream ()); // รับข้อมูลผู้ใช้พื้นฐานจากสตริงไคลเอนต์ inf = reader.readline (); StringTokenizer st = new StringTokenizer (inf, "@"); ผู้ใช้ = ผู้ใช้ใหม่ (st.nexttoken (), st.nexttoken ()); // ข้อเสนอแนะการเชื่อมต่อข้อมูลความสำเร็จนักเขียน. println (user.getName () + user.getip () + "เชื่อมต่อกับเซิร์ฟเวอร์สำเร็จ!"); Writer.flush (); // ข้อเสนอแนะต่อข้อมูลผู้ใช้ออนไลน์ปัจจุบันถ้า (client.size ()> 0) {String temp = ""; สำหรับ (int i = clients.size ()-1; i> = 0; i--) {temp + = (client.get (i) .getUser (). getName () + "/" + ลูกค้า. get (i) .getUser (). getip ()) + "@"; } writer.println ("userlist@" + clients.size () + "@" + temp); Writer.flush (); } // ส่งคำสั่งผู้ใช้ออนไลน์ไปยังผู้ใช้ออนไลน์ทั้งหมดสำหรับ (int i = clients.size ()-1; i> = 0; i--) {client.get (i) .getWriter () println ("เพิ่ม@" + user.getName () + user.getip ()); clients.get (i) .getWriter (). flush (); }} catch (ioexception e) {e.printstacktrace (); }} @suppresswarnings ("การเสื่อมสภาพ") โมฆะสาธารณะเรียกใช้ () {// รับข้อความอย่างต่อเนื่องจากไคลเอนต์สำหรับการประมวลผล ข้อความสตริง = null; ในขณะที่ (จริง) {ลอง {message = reader.readline (); // รับข้อความไคลเอนต์ถ้า (message.equals ("ปิด")) // คำสั่งออฟไลน์ {contentArea.append (this.getUser (). getName () + this.getUser (). getip () + "ออฟไลน์!/r/n"); // ปลดการเชื่อมต่อและปล่อยทรัพยากร reader.close (); Writer.close (); Socket.close (); // ส่งคำสั่งออฟไลน์ของผู้ใช้ไปยังผู้ใช้ออนไลน์ทั้งหมดสำหรับ (int i = clients.size ()-1; i> = 0; i--) {client.get (i) .getWriter () println ("delete@" + user.getName ()); clients.get (i) .getWriter (). flush (); } listmodel.removeElement (user.getName ()); // อัปเดตรายการออนไลน์ // ลบเธรดบริการลูกค้านี้สำหรับ (int i = clients.size ()-1; i> = 0; i--) {ถ้า (client.get (i) .getUser () == ผู้ใช้) clients.remove (i); // ลบเธรดบริการของผู้ใช้นี้ temp.stop (); // หยุดการส่งคืนเธรดบริการนี้; }}} else {dispatcherMessage (ข้อความ); // ส่งต่อข้อความ}} catch (iOexception e) {e.printStackTrace (); }}} // ส่งต่อข้อความโมฆะสาธารณะ dispatcherMessage (ข้อความสตริง) {StringTokenizer StringTokenizer = new StringTokenizer (ข้อความ, "@"); แหล่งที่มาของสตริง = stringTokenizer.nextToken (); string owner = stringtokenizer.nexttoken (); เนื้อหาสตริง = StringTokenizer.nextToken (); ข้อความ = แหล่งที่มา + ":" + เนื้อหา; ContentArea.Append (ข้อความ + "/r/n"); if (owner.equals ("ทั้งหมด")) {// จำนวนมากสำหรับ (int i = clients.size ()-1; i> = 0; i--) {client.get (i) .getWriter (). println (ข้อความ + "(หลายส่ง)"); clients.get (i) .getWriter (). flush (); -client_more.java
นำเข้า java.awt.borderlayout; นำเข้า java.awt.color; นำเข้า java.awt.gridlayout; นำเข้า java.awt.toolkit; นำเข้า java.awt.event.actionevent; นำเข้า java.awt.event.actionListener java.awt.event.windowevent; นำเข้า java.io.bufferedreader; นำเข้า java.io.ioexception; นำเข้า java.io.inputstreamreader; นำเข้า java.io.printwriter; นำเข้า Java.net.socket; javax.swing.defaultlistmodel; นำเข้า Javax.swing.jbutton; นำเข้า Javax.swing.jframe; นำเข้า Javax.swing.jlabel; นำเข้า Javax.swing.jlist; นำเข้า Javax.swing.joptionpane; นำเข้า Javax.swing.jpanel; javax.swing.jsplitpane; นำเข้า javax.swing.jtextarea; นำเข้า Javax.swing.jtextfield; นำเข้า Javax.swing.border.titledBorder; คลาสสาธารณะ client_more {เฟรมส่วนตัว jframe; userlist jlist ส่วนตัว; jtextarea ส่วนตัว textarea; Private Jtextfield Textfield; ส่วนตัว jtextfield txt_port; ส่วนตัว jtextfield txt_hostip; ส่วนตัว jtextfield txt_name; ส่วนตัว JButton BTN_START; ส่วนตัว JButton BTN_STOP; ส่วนตัว JButton BTN_SEND; JPanel Northpanel ส่วนตัว; JPanel ส่วนตัว Southpanel; Jscrollpane Rightscroll ส่วนตัว; jscrollpane ส่วนตัว leftscroll; Private Jsplitpane Centersplit; Private DefaultListModel ListModel; บูลีนส่วนตัว isConnected = false; ซ็อกเก็ตซ็อกเก็ตส่วนตัว นักเขียน Private Printwriter; ตัวอ่านบัฟเฟอร์รีดส่วนตัว; Messagethread ส่วนตัว messagethread; // เธรดที่รับผิดชอบในการรับข้อความแผนที่ส่วนตัว <สตริงผู้ใช้> onlineUsers = new hashmap <สตริงผู้ใช้> (); // ผู้ใช้ออนไลน์ทั้งหมด // วิธีหลัก, รายการโมฆะสาธารณะ } // ดำเนินการส่งโมฆะสาธารณะส่ง () {ถ้า (! isConnected) {joptionpane.showMessageDialog (เฟรม "เซิร์ฟเวอร์ยังไม่ได้เชื่อมต่อกับมันและข้อความไม่สามารถส่ง!", "ข้อผิดพลาด", joptionpane.error_message); กลับ; } สตริงข้อความ = textField.getText (). trim (); if (message == null || message.equals ("")) {joptionpane.showMessagedialog (เฟรม, "ข้อความไม่สามารถว่างเปล่า!", "ข้อผิดพลาด", joptionpane.error_message); กลับ; } sendMessage (frame.getTitle () + "@" + "ทั้งหมด" + "@" + ข้อความ); textfield.settext (null); } // constructor public client_more () {textarea = new jtextarea (); Textarea.setEditable (เท็จ); textarea.setforeground (color.blue); TextField = new JTextField (); txt_port = ใหม่ jtextfield ("6666"); txt_hostip = new jtextfield ("127.0.0.1"); txt_name = new Jtextfield ("Wu Chengqian"); btn_start = new JButton ("การเชื่อมต่อ"); btn_stop = new jbutton ("ตัดการเชื่อมต่อ"); btn_send = new jbutton ("ส่ง"); ListModel = ใหม่ defaultListModel (); userlist = new Jlist (ListModel); NorthPanel = new JPanel (); NorthPanel.SetLayout (ใหม่ gridlayout (1, 7)); Northpanel.add (New Jlabel ("Port")); northpanel.add (txt_port); northpanel.add (ใหม่ JLabel ("เซิร์ฟเวอร์ IP")); northpanel.add (txt_hostip); Northpanel.add (New Jlabel ("ชื่อ")); northpanel.add (txt_name); NorthPanel.Add (BTN_START); NorthPanel.Add (BTN_STOP); NorthPanel.SetBorder (ใหม่ titledBorder ("ข้อมูลการเชื่อมต่อ")); RightsCroll = ใหม่ JScrollpane (Textarea); RightsCroll.SetBorder (ใหม่ titledBorder ("พื้นที่แสดงข้อความ")); leftscroll = ใหม่ jscrollpane (userlist); leftscroll.setBorder (ใหม่ titledBorder ("ผู้ใช้ออนไลน์")); SOUTHPANEL = JPANEL ใหม่ (New BorderLayout ()); SOUTHPANEL.ADD (TextField, "Center"); Southpanel.add (BTN_SEND, "East"); SouthPanel.SetBorder (ใหม่ titledBorder ("ข้อความเขียน")); CentersPlit = ใหม่ JSPlitPane (JSPlitPane.horizontal_split, leftscroll, RightsCroll); CenterSplit.setDividerLocation (100); frame = new JFrame ("ไคลเอนต์"); // เปลี่ยนไอคอนของ jFrame: // frame.seticonimage (toolkit.getdefaulttoolkit (). createimage (client.class.getResource ("qq.png"))); frame.setLayout (New BorderLayout ()); frame.add (Northpanel, "North"); frame.add (Centersplit, "center"); Frame.add (Southpanel, "South"); frame.setsize (600, 400); int screen_width = toolkit.getdefaulttoolkit (). getScreensize (). ความกว้าง; int screen_height = toolkit.getdefaulttoolkit (). getScreensize (). ความสูง; frame.setLocation ((screen_width - frame.getWidth ()) / 2, (screen_height - frame.getheight ()) / 2); frame.setVisible (จริง); // เหตุการณ์เมื่อกด Enter ในกล่องข้อความเพื่อเขียนข้อความ TextField.AddactionListener (ใหม่ actionListener () {โมฆะสาธารณะ ActionPerformed (ActionEvent Arg0) {ส่ง ();}}); // เหตุการณ์ btn_send.addactionListener (ใหม่ actionListener () {โมฆะสาธารณะ ActionPerformed (ActionEvent E) {send ();}}); // เหตุการณ์ btn_start.addactionListener (ใหม่ actionListener () {โมฆะสาธารณะ actionperformed (actionEvent e) {int port; ถ้า (isconnected) {joptionpane.showmessagedialog (Frame, try {try {try retnes) Integer.parseint (txt_port.getText (). trim ()); hostip.equals ("") {โยนข้อยกเว้นใหม่ ("ชื่อและเซิร์ฟเวอร์ไม่สามารถว่างเปล่า!"); JOptionPane.ShowMessageHialog (Frame, Exc.getMessage (), "ข้อผิดพลาด", Joptionpane.error_message);}}}); // เหตุการณ์ btn_stop.addactionListener (ใหม่ actionListener () {โมฆะสาธารณะ actionperformed (actionEvent e) {ถ้า (! isconnected) {joptionpane.ShowMessagedialog (เฟรม "มันอยู่ในสถานะที่ไม่เชื่อมโยงกัน Boolean Flag = CloseConnection (); // ตัดการเชื่อมต่อถ้า (Flag == False) {โยนข้อยกเว้นใหม่ ("ข้อยกเว้นเกิดขึ้นเมื่อตัดการเชื่อมต่อ!"); joptionpane.error_message);}}}); // เหตุการณ์เมื่อปิดเฟรมหน้าต่าง addwindowListener (windowadapter ใหม่ () {โมฆะสาธารณะการปิดหน้าต่าง (windowevent e) {ถ้า (isconnected) {closeconnection (); // ปิดการเชื่อมต่อ} system.exit (0); // ออกจากโปรแกรม}}); }/ ** * เชื่อมต่อกับเซิร์ฟเวอร์ * * @param พอร์ต * @param hostip * @param ชื่อ */ บูลีนสาธารณะเชื่อมต่อ (พอร์ต int, สตริงโฮสต์, ชื่อสตริง) {// เชื่อมต่อกับเซิร์ฟเวอร์ลอง {socket = ซ็อกเก็ตใหม่ (hostip, พอร์ต); // สร้างการเชื่อมต่อตามพอร์ต reader = ใหม่ bufferedReader (ใหม่ inputStreamReader (ซ็อกเก็ต. getInputStream ())); // ส่งข้อมูลพื้นฐานของผู้ใช้ไคลเอนต์ (ชื่อผู้ใช้และที่อยู่ IP) SendMessage (ชื่อ + "@" + socket.getLocalAddress (). ToString ()); // เปิดเธรดเพื่อรับข้อความ messagethread = new messagethread (reader, textarea); messagethread.start (); isConnected = true; // ได้รับการเชื่อมต่อเพื่อส่งคืนจริง; } catch (exception e) {textarea.append ("เซิร์ฟเวอร์ที่มีหมายเลขพอร์ต:" + พอร์ต + "ที่อยู่ IP:" + hostip + "ล้มเหลว!" + "/r/n"); isConnected = false; // return false เมื่อไม่เชื่อมต่อ; }} / ** * ส่งข้อความ * * @param ข้อความ * / โมฆะสาธารณะ sendMessage (ข้อความสตริง) {writer.println (ข้อความ); Writer.flush (); }/ *** ไคลเอนต์ปิดการเชื่อมต่ออย่างแข็งขัน*/ @suppresswarnings ("deprecation") การเชื่อมต่อแบบบูลีนแบบซิงโครน } if (writer! = null) {writer.close (); } if (ซ็อกเก็ต! = null) {socket.close (); } isConnected = false; กลับมาจริง; } catch (ioexception e1) {e1.printstacktrace (); isConnected = true; กลับเท็จ; }} // เธรดที่ได้รับข้อความ MessagetHread อย่างต่อเนื่องขยายเธรด {Private BufferedReader Reader; jtextarea ส่วนตัว textarea; // วิธีการสร้างสำหรับการรับข้อความข้อความสาธารณะ messagethread (bufferedreader reader, jtextarea textarea) {this.reader = reader; this.textarea = textarea; } // ปิดการเชื่อมต่อการเชื่อมต่อสาธารณะที่ซิงโครไนซ์ closecon () พ่นข้อยกเว้น {// ล้างผู้ใช้ listmodel.removeallelements (); // ปิดการเชื่อมต่ออย่างอดทนและปล่อยทรัพยากรถ้า (reader! = null) {reader.close (); } if (writer! = null) {writer.close (); } if (ซ็อกเก็ต! = null) {socket.close (); } isConnected = false; // แก้ไขสถานะเป็น disconnect} void public void run () {string message = ""; ในขณะที่ (จริง) {ลอง {message = reader.readline (); StringTokenizer StringTokenizer = new StringTokenizer (ข้อความ, "/@"); String Command = StringTokenizer.nextToken (); // คำสั่งถ้า (command.equals ("ปิด")) // คำสั่งปิดเซิร์ฟเวอร์ {textarea.append ("เซิร์ฟเวอร์ปิด!/r/n"); closecon (); // ปิดการเชื่อมต่อแบบส่งคืน; // end เธรด} อื่นถ้า (command.equals ("เพิ่ม")) {// ผู้ใช้บางคนกำลังอัปเดตชื่อผู้ใช้สตริงออนไลน์ = ""; string userip = ""; if ((username = stringtokenizer.nexttoken ())! = null && (userip = stringtokenizer.nexttoken ())! = null) {ผู้ใช้ผู้ใช้ = ผู้ใช้ใหม่ (ชื่อผู้ใช้, userip); OnlineUsers.put (ชื่อผู้ใช้ผู้ใช้); ListModel.Addelement (ชื่อผู้ใช้); }} else if (command.equals ("delete")) {// ผู้ใช้บางคนกำลังลดลงชื่อผู้ใช้สตริงออนไลน์ = stringTokenIzer.nextToken (); ผู้ใช้ user = (ผู้ใช้) onlineUsers.get (ชื่อผู้ใช้); OnlineUsers.remove (ผู้ใช้); ListModel.removeElement (ชื่อผู้ใช้); } else if (command.equals ("userlist")) {// โหลดรายการผู้ใช้ออนไลน์ int size = จำนวนเต็ม. parseint (stringTokenizer.nextToken ()); String username = null; string userip = null; สำหรับ (int i = 0; i <size; i ++) {username = stringtokenizer.nexttoken (); userip = stringTokenizer.nexttoken (); ผู้ใช้ผู้ใช้ = ผู้ใช้ใหม่ (ชื่อผู้ใช้, ผู้ใช้); OnlineUsers.put (ชื่อผู้ใช้ผู้ใช้); ListModel.Addelement (ชื่อผู้ใช้); }} อื่นถ้า (command.equals ("max")) {// จำนวนคนมาถึงขีด จำกัด บน textarea.append (StringTokenizer.nexttoken () + StringTokenizer.nexttoken () + "/r/n"); closecon (); // ปิดการเชื่อมต่อ joptionpane.showmessagedialog (เฟรม "บัฟเฟอร์เซิร์ฟเวอร์เต็ม!", "ข้อผิดพลาด", joptionpane.error_message); return; // end thread} else {// ข้อความปกติ textarea.append (ข้อความ + "/r/n"); }} catch (ioexception e) {e.printstacktrace (); } catch (exception e) {e.printstacktrace (); -ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น