Karena saya perlu membuat desain kursus jaringan komputer jaringan dan tidak ingin melakukan kabel jaringan atau konfigurasi router LAN, dll., Saya akhirnya memutuskan untuk menggunakan soket untuk menulis ruang obrolan LAN berdasarkan java:
Untuk informasi lebih lanjut tentang pemrograman soket dan jaringan, silakan merujuk ke artikel saya yang lain: pemrograman berbasis soket Java
Program ini didasarkan pada struktur C/S, yaitu mode server klien.
Server:
IP default adalah IP asli
Kedua belah pihak perlu menentukan nomor port untuk mengatur jumlah maksimum orang yang terhubung. Antarmuka dapat dimulai dan ditutup untuk menampilkan pengguna dan nama online (unit ini tidak ditampilkan di sini)
Klien:
Perlu secara manual mengatur Alamat IP Server (LAN)
Atur secara manual nomor port dan masukkan nama untuk menghubungkan dan lepaskan program yang menjalankan antarmuka sebagai berikut:
Server:
Klien:
Saya akan mengunggah kode tertentu di akhir.
Ada banyak kekurangan dalam perangkat lunak, seperti:
Tidak ada optimasi persimpangan dengan database: semua pengguna dapat disimpan dalam database, dan catatan obrolan juga dapat ditempatkan dalam database. Optimalisasi obrolan satu-ke-satu tidak diimplementasikan: masih ada banyak kekurangan dalam metode mendefinisikan kembali obrolan satu-ke-satu. Jika Anda tertarik, kembalilah dan pelajari perlahan.
Berikut ini adalah tiga kode untuk program:
User.java
Pengguna kelas publik { / *** Kelas Informasi Pengguna* Digunakan untuk merekam Informasi Pribadi Pengguna: Nama dan IP* / Nama String Privat; ip string pribadi; pengguna publik (nama string, string ip) {this.name = name; this.ip = ip; } public string getName () {return name; } public void setName (name string) {this.name = name; } string publik getIp () {return ip; } public void setip (string ip) {this.ip = ip; }}Server_more.java
Impor java.awt.borderlayout; import java.awt.color; impor java.awt.gridlayout; import java.awt.toolkit; import java.awt.event.actionevent; import java.awt.acticeListener; impor java.awt.event.event.event. java.awt.event.windowevent; impor java.io.bufferedReader; impor java.io.ioexception; impor java.io.inputStreamReader; impor java.io.printwriter; impor java.net.bindException; impor java.net.serversocks; java.util.arraylist; impor java.util.stringtokenizer; impor javax.swing.defaultlistModel; impor javax.swing.jbutton; impor javax.swing.jframe; impor javax.swing.jlabel; impor javax.swing.jlist; javax.swing.jpanel; import javax.swing.jscrollpane; import javax.swing.jsplitpane; import javax.swing.jtextarea; import javax.swing.jtextfield; import javax.swing.border.titledborder; server public class server_more {private {private {javax.swing.bordled. ContentArea JtextArea Private; // bidang teks pribadi jTextfield txt_message; // Digunakan untuk menampilkan informasi teks pribadi jTextfield txt_max; // Tetapkan jumlah maksimum orang yang terhubung dengan JTextfield TXT_PORT; // atur nomor port private jbutton btn_start; // Mulai Tombol Private JButton BTN_STOP; // lepaskan tombol pribadi jbutton btn_send; // Kirim tombol pribadi jpanel northpanel; // Panel Utara Private Jpanel Southpanel; // Panel Selatan Private Jscrollpane Rightpanel; // Left Scroll Bar Private Jscrollpane Leftpanel; // bilah gulir kanan private jsplitpane centersplit; // split line private jlist userlist; // komponen tunggal private DefaultListModel ListModel; server server private server; ServerThread Private ServerThread; klien arraylist pribadi <ClientThread>; private boolean isStart = false; // metode utama, entri eksekusi program statis public static main (string [] args) {baru server_more (); } // Jalankan pesan Kirim public void kirim () {if (! IsStart) {joptionpane.showmessagealog (frame, "server belum dimulai, dan pesan tidak dapat dikirim!", "Kesalahan", joptionpane.error_message); kembali; } if (client.size () == 0) {jOptionPane.showmessagealog (bingkai, "Tidak ada pengguna online, pesan tidak dapat dikirim!", "error", joptionpane.error_message); kembali; } String message = txt_message.getText (). Trim (); if (message == null || message.equals ("")) {joptionpane.showmessagealog (frame, "pesan tidak bisa kosong!", "error", joptionpane.error_message); kembali; } SendServerMessage (pesan); // Pesan Server Mass ContentArea.append ("Server:" + txt_message.getText () + "/r/n"); txt_message.setText (null); } // Bangun metode drop server public_more () {frame = new jframe ("server"); // Ubah ikon jFrame: //frame.seticonimage(toolkit.getDefaultToolKit().createImage(client.class.getResource("QQ.png "))); //frame.seticonimage(toolkit.getDefaultToolKit().createImage(server.class.getResource("QQ.png "))); contentArea = jTextArea () baru; contentArea.seteditable (false); ContentArea.setForeground (Color.Blue); txt_message = new jTextField (); txt_max = JTextField baru ("30"); txt_port = JTextField baru ("6666"); btn_start = jbutton baru ("start"); btn_stop = jbutton baru ("stop"); btn_send = jbutton baru ("kirim"); btn_stop.setenabled (false); listModel = new DefaultListModel (); UserList = JLIST baru (ListModel); southpanel = jpanel baru (borderlayout baru ()); southpanel.setborder (judul baru ("tulis pesan")); southpanel.add (txt_message, "center"); southpanel.add (btn_send, "timur"); leftpanel = jscrollpane baru (daftar pengguna); leftpanel.setborder (judul baru ("pengguna online")); RightPanel = jscrollpane baru (ContentArea); rightpanel.setborder (judul baru ("Area Tampilan Pesan")); centersplit = jsplitpane baru (jsplitpane.horizontal_split, leftpanel, rightpanel); centersplit.setDividerLocation (100); northpanel = jpanel baru (); northpanel.setlayout (Gridlayout baru (1, 6)); northpanel.add (Jlabel baru ("batas atas")); northpanel.add (txt_max); northpanel.add (Jlabel baru ("port")); northpanel.add (txt_port); northpanel.add (btn_start); northpanel.add (btn_stop); northpanel.setborder (judul baru ("informasi konfigurasi")); frame.setLayout (borderlayout baru ()); Frame.Add (Northpanel, "North"); frame.add (centersplit, "center"); Frame.Add (Southpanel, "South"); frame.setsize (600, 400); //frame.setsize(toolkit.getDefaultToolKit (). GetScreensize ()); // atur layar penuh int screen_width = toolkit.getDefaultToolKit (). GetScreensize (). Width; int screen_height = toolkit.getDefaultToolKit (). getscreensize (). tinggi; frame.setLocation ((screen_width - frame.getWidth ()) / 2, (screen_height - frame.getHeight ()) / 2); frame.setVisible (true); // peristiwa saat menutup bingkai window.addwindowlistener (windowAdapter baru () {public void windowclosing (windowevent e) {if (isStart) {closeServer (); // tutup server} system.exit (0); // program keluar}}); // acara txt_message.addactionListener (actionListener baru () {public void actionPerformed (actionEvent e) {send ();}}); // event btn_send.addactionListener (actionListener () {public void actionPerformed (actionEvent arg0) {send ();}}); // Event btn_start.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (isStart) { JOptionPane.showMessageDialog(frame, "The server is already in the startup state, do not start repeatedly! ", "Error", JOptionPane.ERROR_MESSAGE); return; } int max; int port; try { try {max = integer.parseint (txt_max.getText ()); Integer.parseint (txt_port.gettext ()); + port + "/r/n"); txt_max.setEnabled (false); txt_port.setEnabled (false); btn_stop.setEnabled (true); } catch (exception exc) {jOptionPane.showmessagealog (frame, exc.getmessage (), "error", joptionpane.error_message); }}}); // acara btn_stop.addactionListener (actionListener () {public void actionPerformed (actionEvent e) {if (! IsStart) {jOptionPane.showmessagealog (frame, "server belum dimulai, tidak perlu berhenti!" btn_start.setenabled (true); JOPTIONPANE.SHOWMESSADEIALOG (bingkai, "Pengecualian terjadi ketika server dihentikan!", "Kesalahan", joptionpane.error_message); } // Mulai server public void serverstart (int max, int port) melempar java.net.bindException {try {clients = new ArrayList <ClientThread> (); ServerSocket = New ServerSocket (port); serverThread = serverThread baru (serversocket, max); serverthread.start (); isStart = true; } catch (BindException e) {isStart = false; Lempar BindException baru ("Nomor port telah ditempati, tolong ubah!"); } catch (Exception e1) {e1.printstacktrace (); isStart = false; Lempar BindException baru ("Mulai Pengecualian Server!"); }} // Tutup server @suppresswarnings ("Deprecation") public void closeServer () {coba {if (serverThread! = Null) serverThread.stop (); // hentikan utas server untuk (int i = klien. klien.get (i) .getWriter (). flush (); // Lepaskan sumber daya klien.get (i) .stop (); // hentikan utas ini melayani klien klien. Get (i) .reader.close (); Client.get (i) .writer.close (); Client.get (i) .socket.close (); Clients.remove (i); } if (serversocket! = null) {serversocket.close (); // tutup koneksi sisi-server} listModel.removeAllements (); // hapus daftar pengguna isStart = false; } catch (ioException e) {e.printstacktrace (); isStart = true; }} // Pesan server massal public void sendServerMessage (pesan string) {for (int i = client.size ()-1; i> = 0; i--) {client.get (i) .getWriter (). Println ("server:" + pesan + "(ganda kirim)"); klien.get (i) .getWriter (). flush (); }} // Server Thread Class ServerThread Extends Thread {Private ServerSocket ServerSocket; private int max; // jumlah atas orang // Membangun metode server server server publik (server serversocket, int max) {this.serversocket = serversocket; this.max = max; } public void run () {while (true) {// Tetap menunggu tautan klien coba {socket socket = serversocket.accept (); if (client.size () == max) {// Jika jumlah maksimum orang telah tercapai bufferedReader r = BufferedReader baru (inputStreamReader baru (socket.getInputStream ())); Printwriter w = printwriter baru (socket .getoutputStream ()); // menerima informasi pengguna dasar dari string klien INF = R.Readline (); StringTokenizer st = new stringTokenizer (inf, "@"); Pengguna pengguna = pengguna baru (st.nextToken (), st.nexttoken ()); // Informasi Sukses Koneksi Umpan Balik W.Println ("MAX@Server: Maaf," + user.getname () + user.getip () + ", jumlah orang yang online di server telah mencapai batas atas, coba terhubung nanti!"); w.flush (); // lepaskan sumber daya r.close (); w.close (); socket.close (); melanjutkan; } ClientThread klien = klien baru (soket); client.start (); // Mulai utas untuk layanan klien ini Client.Add (klien); listModel.addeLement (client.getUser (). getName ()); // Perbarui daftar online contentAreaA.Append (client.getUser (). getName () + client.getUser (). getip () + "online!/r/n"); } catch (ioException e) {e.printstacktrace (); }}}}} // Thread Melayani kelas klien ClientThread Extends Thread {Private Socket Socket; Pembaca Private Bufferederer; penulis printwriter pribadi; Pengguna Pribadi; Public BufferedReader getReader () {return reader; } public printwriter getWriter () {return writer; } pengguna publik getUser () {return user; } // Konstruktor klien klien klien umum (soket soket) {coba {this.socket = soket; pembaca = BufferedReader baru (inputStreamReader baru (socket .getInputStream ())); penulis = printwriter baru (socket.getoutputStream ()); // menerima informasi pengguna dasar dari string klien INF = reader.readline (); StringTokenizer st = new stringTokenizer (inf, "@"); pengguna = pengguna baru (st.nexttoken (), st.nexttoken ()); // Koneksi Umpan Balik Informasi Sukses Writer.println (user.getName () + user.getip () + "Sambungkan ke server berhasil!"); writer.flush (); // Umpan Balik ke Informasi Pengguna Online Saat Ini if (client.size ()> 0) {string temp = ""; untuk (int i = client.size ()-1; i> = 0; i--) {temp + = (client.get (i) .getUser (). getName () + "/" + Client .get (i) .getUser (). getip ()) + "@"; } writer.println ("userlist@" + client.size () + "@" + temp); writer.flush (); } // Kirim perintah pengguna online ke semua pengguna online untuk (int i = client.size ()-1; i> = 0; i--) {client.get (i) .getWriter (). Println ("add@" + user.getname () + user.getip ()); klien.get (i) .getWriter (). flush (); }} catch (ioException e) {E.PrintStackTrace (); }} @SuppressWarnings ("Deprecation") public void run () {// terus menerima pesan dari klien untuk diproses. String message = null; while (true) {coba {message = reader.readline (); // Terima pesan klien jika (pesan // lepaskan dan rilis sumber daya pembaca.close (); writer.close (); socket.close (); // Kirim perintah offline pengguna ke semua pengguna online untuk (int i = client.size ()-1; i> = 0; i--) {client.get (i) .getWriter (). Println ("delete@" + user.getname ()); klien.get (i) .getWriter (). flush (); } listModel.removeElement (user.getName ()); // Perbarui daftar online // hapus utas layanan klien ini untuk (int i = client.size ()-1; i> = 0; i--) {if (client.get (i) .getUser () == USER) {clientThread temp = client.get (i); Client.Remove (i); // Hapus Thread Layanan Pengguna ini Temp.Stop (); // Hentikan pengembalian utas layanan ini; }}} else {DispatcherMessage (pesan); // Pesan Tersedia}} catch (ioException e) {e.printstacktrace (); }}} // Maju pesan public void dispatcherMessage (string message) {stringTokenizer stringTokenizer = new stringTokenizer (pesan, "@"); Sumber String = StringTokenizer.nextToken (); String owner = stringTokenizer.nextToken (); String content = stringTokenizer.nextToken (); pesan = sumber + ":" + konten; ContentArea.Append (pesan + "/r/n"); if (owner.equals ("all")) {// bulk for (int i = client.size ()-1; i> = 0; i--) {client.get (i) .getWriter (). println (pesan + "(ganda kirim)"); klien.get (i) .getWriter (). flush (); }}}}}}}Client_more.java
Impor java.awt.borderlayout; import java.awt.color; impor java.awt.gridlayout; import java.awt.toolkit; import java.awt.event.actionevent; import java.awt.acticeListener; impor java.awt.event.event.event. java.awt.event.windowevent; impor java.io.bufferedreader; impor java.io.ioexception; impor java.io.inputStreamReader; impor java.io.printwriter; impor java.net.socket; impor java.util.hashmaap; java.util.stringtokenizer; import javax.swing.defaultlistModel; impor javax.swing.jbutton; impor javax.swing.jframe; import javax.swing.jlabel; impor javax.swing.jlist; impor javax.swing.joptionpane; javax.swing.jscrollpane; import javax.swing.jsplitpane; import javax.swing.jtextarea; import javax.swing.jtextfield; import javax.swing.border.titledborder; kelas publik client_more {bingkai jframe pribadi; Daftar Pengguna Private JList; Private JtextArea TexTarea; Private JTextfield Textfield; Private JTextfield TXT_PORT; Private JTextField TXT_HOSTIP; Private JTextField txt_name; Private JButton BTN_Start; Private JButton BTN_STOP; Private JButton BTN_Send; Private Jpanel Northpanel; Jpanel Private Southpanel; Private Jscrollpane Rightscroll; Private Jscrollpane Leftscroll; centersplit jsplitpane pribadi; Private DefaultListModel ListModel; private boolean isConnected = false; soket soket pribadi; penulis printwriter pribadi; Pembaca Private Bufferederer; Private MessageThread MessageThread; // Thread yang bertanggung jawab untuk menerima pesan peta pribadi <String, User> onlineAsers = hashmap baru <string, user> (); // semua pengguna online // metode utama, entri program statis public static main (string [] args) {client_more baru (); } // Jalankan pengiriman public void send () {if (! IsConnected) {joptionpane.showmessagealog (frame, "server belum terhubung dengannya, dan pesan tidak dapat dikirim!", "Kesalahan", joptionpane.error_message); kembali; } String message = textfield.getText (). Trim (); if (message == null || message.equals ("")) {joptionpane.showmessagealog (frame, "pesan tidak bisa kosong!", "error", joptionpane.error_message); kembali; } sendMessage (frame.gettitle () + "@" + "all" + "@" + pesan); textfield.setText (null); } // konstruktor public client_more () {TextAreA = new jTextArea (); TextArea.seteditable (false); TextArea.setForeground (Color.Blue); textfield = new jTextField (); txt_port = JTextField baru ("6666"); txt_hostip = jTextField baru ("127.0.0.1"); txt_name = JTextField baru ("Wu Chengqian"); btn_start = jbutton baru ("koneksi"); btn_stop = jbutton baru ("Disconnect"); btn_send = jbutton baru ("kirim"); listModel = new DefaultListModel (); UserList = JLIST baru (ListModel); northpanel = jpanel baru (); northpanel.setlayout (Gridlayout baru (1, 7)); northpanel.add (Jlabel baru ("port")); northpanel.add (txt_port); northpanel.add (jlabel baru ("server ip")); northpanel.add (txt_hostip); northpanel.add (jlabel baru ("nama")); northpanel.add (txt_name); northpanel.add (btn_start); northpanel.add (btn_stop); northpanel.setborder (judul baru ("informasi koneksi")); RightsCroll = JScrollPane baru (TextArea); HirsCroll.SetBorder (judul baru ("Area Tampilan Pesan")); LeftScroll = JScrollPane baru (UserList); leftscroll.setborder (judul baru ("pengguna online")); southpanel = jpanel baru (borderlayout baru ()); Southpanel.add (Textfield, "Center"); southpanel.add (btn_send, "timur"); southpanel.setborder (judul baru ("tulis pesan")); centersplit = jsplitpane baru (jsplitpane.horizontal_split, leftscroll, rightscroll); centersplit.setDividerLocation (100); frame = jframe baru ("klien"); // Ubah ikon jFrame: // frame.seticonimage (toolkit.getDefaultToolKit (). CreateImage (client.class.getResource ("qq.png")))); frame.setLayout (borderlayout baru ()); Frame.Add (Northpanel, "North"); frame.add (centersplit, "center"); Frame.Add (Southpanel, "South"); frame.setsize (600, 400); int screen_width = toolkit.getDefaultToolKit (). getscreensize (). width; int screen_height = toolkit.getDefaultToolKit (). getscreensize (). tinggi; frame.setLocation ((screen_width - frame.getWidth ()) / 2, (screen_height - frame.getHeight ()) / 2); frame.setVisible (true); // acara saat menekan enter di kotak teks untuk menulis pesan teksfield.addactionListener (actionListener () {public void actionPerformed (actionEvent arg0) {send ();}}); // acara btn_send.addactionListener (actionListener () {public void actionPerformed (actionEvent e) {send ();}}); // acara btn_start.addactionListener (actionListener () {public void actionPerformed (actionEvent e) {int port; if (isConnected) {jOptionpane.showmessageDialog (bingkai, "sudah ada di koneksi, jangan mengulangi koneksi!", "Kesalahan", joption, "sudah ada di koneksi, jangan mengulangi koneksi!", "Kesalahan", JOPTION, "JOPTION, JOURPANE), JOURPEAGE (JOUSTIES NET Ulang Koneksi!" Integer.parseint (txt_port.getText (). Trim ()); HOSTIP. {JOptionPane.ShowMessageDialog (frame, excetmessage (), "error", joptionpane.error_message); // acara btn_stop.addactionListener (actionListener () {public void actionPerformed (actionEvent e) {if (! IsConnected) {jOptionPane.showmessageDialog (bingkai, "Jor -retrype. Bendera = CloseConnection (); // Putuskan IF (Bendera == Salah) {Lempar Pengecualian Baru ("Pengecualian Terjadi Saat Putus!"); Joptionpane.error_message);}}}); // peristiwa saat menutup bingkai window.addwindowlistener (windowadapter baru () {public void windowclosing (windowevent e) {if (isConnected) {closeConnection (); // tutup koneksi} system.exit (0); // Keluar dari program}}); }/ ** * Sambungkan ke server * * @param port * @param hosttip * @param nama */ public boolean connectserver (port int, hostip string, nama string) {// terhubung ke server coba {socket = new socket (hosttip, port); // buat koneksi berdasarkan nomor port dan server IP writer = new printwriter (socket. pembaca = BufferedReader baru (inputStreamReader baru (socket .getInputStream ())); // Kirim informasi dasar dari pengguna klien (nama pengguna dan alamat IP) sendmessage (name + "@" + socket.getLocalAddress (). ToString ()); // buka utas untuk menerima pesan messagethread = new MessageThread (pembaca, textarea); messagethread.start (); isConnected = true; // telah terhubung untuk mengembalikan true; } catch (Exception e) {TextArea.Append ("Server dengan Nomor Port:" + Port + "Alamat IP:" + Hostip + "Gagal!" + "/R/N"); isConnected = false; // return false pada tidak terhubung; }} / ** * Kirim pesan * * @param pesan * / public void sendMessage (pesan string) {writer.println (pesan); writer.flush (); }/ *** Klien secara aktif menutup koneksi*/ @suppressWarnings ("Deprecation") Publik yang disinkronkan boolean closeConnection () {coba {sendMessage ("tutup"); // Kirim perintah pemutus ke server messagethread.stop (); // stoping menerima utas pesan // rilis sumber daya ife (reader = noulkose (); } if (writer! = null) {writer.close (); } if (socket! = null) {socket.close (); } isConnected = false; Kembali Benar; } catch (ioException e1) {e1.printstacktrace (); isConnected = true; mengembalikan false; }} // Thread yang terus -menerus menerima kelas pesan MessageThread Extends Thread {Private BufferedReader Reader; Private JtextArea TexTarea; // Metode Membangun untuk menerima utas pesan PUBLIK MESSAGETHREAD (BufferedReader Reader, JTextArea TexTarea) {this.reader = pembaca; this.textArea = textarea; } // Secara pasif Tutup koneksi public yang disinkronkan void closeCon () melempar Exception {// hapus listmodel.removeAllements (); // Tutup secara pasif koneksi dan lepaskan sumber daya jika (pembaca! = Null) {reader.close (); } if (writer! = null) {writer.close (); } if (socket! = null) {socket.close (); } isConnected = false; // Ubah status untuk memutuskan} public void run () {string message = ""; while (true) {coba {message = reader.readline (); StringTokenizer stringTokenizer = new stringTokenizer (pesan, "/@"); Command string = stringTokenizer.nextToken (); // Command if (command.equals ("tutup")) // server command tertutup {textArea.append ("server tertutup!/R/n"); closeCon (); // secara pasif Tutup kembali koneksi; // end thread} else if (command.equals ("add")) {// beberapa pengguna memperbarui daftar online string username = ""; String userip = ""; if ((userName = stringTokenizer.nextToken ())! = null && (userip = stringTokenizer.nextToken ())! = null) {user user = pengguna baru (username, userip); onlineAsers.put (nama pengguna, pengguna); listModel.addelement (nama pengguna); }} lain if (command.equals ("delete")) {// Beberapa pengguna sedang menurunkan daftar pengguna string online = stringTokenizer.nextToken (); Pengguna pengguna = (pengguna) onlineAsers.get (nama pengguna); onlineAsers.remove (pengguna); listModel.removeelement (nama pengguna); } else if (command.equals ("userList")) {// Muat daftar pengguna online int ukuran = integer .parseInt (stringTokenizer.nextToken ()); String username = null; String userip = null; untuk (int i = 0; i <size; i ++) {userName = stringTokenizer.nextToken (); userip = stringTokenizer.nextToken (); Pengguna pengguna = pengguna baru (nama pengguna, userip); onlineAsers.put (nama pengguna, pengguna); listModel.addelement (nama pengguna); }} lain if (command.equals ("max")) {// Jumlah orang telah mencapai batas atas textarea.append (stringTokenizer.nextToken () + stringTokenizer.nextToken () + "/r/n"); closeCon (); // Secara pasif Tutup koneksi joptionpane.showmessagedialog (frame, "buffer server penuh!", "Kesalahan", joptionpane.error_message); return; // end thread} else {// pesan normal TextArea.Append (pesan + "/r/n"); }} catch (ioException e) {E.PrintStackTrace (); } catch (Exception e) {E.PrintStackTrace (); }}}}}Di atas adalah semua konten artikel ini. Saya berharap ini akan membantu untuk pembelajaran semua orang dan saya harap semua orang akan lebih mendukung wulin.com.