ネットワークコンピューターネットワークコースの設計を作成する必要があり、ネットワーク配線やLANルーターの構成などをやりたくないので、ついにSocketを使用してJavaに基づいてLANチャットルームを作成することにしました。
ソケットとネットワークのプログラミングの詳細については、他の記事を参照してください。JavaSocketベースのプログラミング
このプログラムは、C/S構造、つまりクライアントサーバーモードに基づいています。
サーバ:
デフォルトのIPはネイティブIPです
両当事者は、接続された人の最大数を設定するためにポート番号を決定する必要があります。インターフェイスを起動して閉じてオンラインユーザーと名前を表示できます(このユニットはここに表示されません)
クライアント:
サーバーIPアドレス(LAN)を手動で設定する必要があります
ポート番号を手動で設定し、名前を入力して、次のようにプログラムを実行しているインターフェイスを接続して切断します。
サーバ:
クライアント:
最後に特定のコードをアップロードします。
ソフトウェアには、次のような多くの欠点があります。
データベースには交差点の最適化はありません。すべてのユーザーをデータベースに保存でき、チャットレコードをデータベースに配置することもできます。 1対1のチャット最適化は実装されていません。1対1のチャットを再定義する方法にはまだ多くの欠点があります。あなたがそれに興味があるなら、戻ってきてゆっくりと勉強してください。
以下は、プログラムの3つのコードです。
user.java
パブリッククラスユーザー{ / ***ユーザー情報クラス*ユーザーの個人情報を記録するために使用:名前とip* / private文字列名。プライベート文字列IP; public user(string name、string ip){this.name = name; this.ip = ip; } public string getname(){return name; } public void setName(string name){this.name = name; } public string getIp(){return ip; } public void setip(string ip){this.ip = ip; }}server_more.java
Import java.awt.borderlayout; Import java.awt.color; Import java.awt.gridlayout; Import java.awt.toolkit; Import java.awt.event.actionevent; Import java.awt.event.event.actionlistener; Import Java.awt.event.windowadapter; java.awt.event.windowevent; import java.io.bufferedreader; Import java.io.ioexception; Impate java.io.inputStreamReader; Import java.net.bindexception; import java.net.net.net.serversocket; import java.net. Java.util.StringTokenizer; Import javax.swing.defaultlistmodel; Import javax.swing.jbutton; Import javax.swing.jframe; Import javax.swing.jlabel; Import javax.swing.jlist; import javax.swing.swing.swing.javax.swing.javax.swing.swing.swing.swing.javax.swing.javax.swing.javax.swing.javax.swing.javax.swing.javax.swing.javax. javax.swing.jscrollpane; Import javax.swing.jsplitpane; Import javax.swing.jtextarea; import javax.swing.jtextfield; Import javax.swing.border.titledborder; public class server_more {private jframe frame;プライベートJTextarea contentarea; //テキストフィールドプライベートjtextfield txt_message; //テキスト情報を表示するために使用されますprivate jtextfield txt_max; //プライベートJTextfield txt_portを接続する人の最大数を設定します。 //ポート番号を設定Private jbutton btn_start; //スタートボタンプライベートjbutton btn_stop; //ボタンを切断しますプライベートjbutton btn_send; //プライベートJPanel Northpanelを送信します。 //ノースパネルプライベートJPanel Southpanel; //サウスパネルプライベートjscrollpane rightpanel; //左スクロールバーPrivate JScrollpane Leftpanel; //右スクロールバープライベートjsplitpaneセンタースプリット。 //スプリットラインプライベートJLISTユーザーリスト。 //単一コンポーネントプライベートdefaultListModel listModel;プライベートサーバーソケットサーバーソケット。 private serverThread ServerThread; Private ArrayList <ClientThread>クライアント; private boolean isstart = false; //メインメソッド、プログラム実行エントリpublic static void main(string [] args){new Server_more(); } // public public void send(){if(!isstart){joptionpane.showmessageialog(frame、 "サーバーはまだ起動しておらず、メッセージを送信できない!"、 "error"、joptionpane.error_message);戻る; } if(clients.size()== 0){joptionpane.showmessageialog(frame、 "ユーザーはオンラインではなく、メッセージを送信できません!"、 "error"、joptionpane.error_message);戻る; } string message = txt_message.getText()。trim(); if(message == null || message.equals( "")){joptionpane.showmessageialog(frame、 "message na couns each!"、 "error"、joptionpane.error_message);戻る; } sendservermessage(message); // Mass Server Message contentarea.append( "server:" + txt_message.getText() + "/r/n"); txt_message.settext(null); } //ドロップメソッドを作成しますpublic server_more(){frame = new JFrame( "server"); // 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.setedable(false); contentarea.setforeground(color.blue); txt_message = new jtextfield(); txt_max = new jtextfield( "30"); txt_port = new jtextfield( "6666"); btn_start = new jbutton( "start"); btn_stop = new jbutton( "stop"); btn_send = new jbutton( "send"); btn_stop.setEnabled(false); listModel = new DefaultListModel(); userlist = new Jlist(listmodel); southpanel = new jpanel(new borderlayout()); Southpanel.setborder(new Titledborder( "write message")); southpanel.add(txt_message、 "center"); southpanel.add(btn_send、 "east"); reptpanel = new JScrollpane(userlist); leftpanel.setborder(new Titledborder( "オンラインユーザー")); rightpanel = new jscrollpane(contentarea); rightpanel.setborder(new Titledborder( "メッセージ表示領域")); centersplit = new jsplitpane(jsplitpane.horizontal_split、leftpanel、rightpanel); centersplit.setDividerLocation(100); northpanel = new JPanel(); northpanel.setlayout(new gridlayout(1、6)); northpanel.add(new Jlabel( "上限")); northpanel.add(txt_max); northpanel.add(new Jlabel( "Port")); northpanel.add(txt_port); northpanel.add(btn_start); northpanel.add(btn_stop); northpanel.setborder(new Titledborder( "Configuration Information")); 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()。width; int screen_height = toolkit.getDefaultToolkit()。getScreensize()。height; frame.setlocation((screen_width -frame.getWidth()) / 2、(screen_height -frame.getheigh() / 2); frame.setVisible(true); //ウィンドウフレームを閉じるときのイベント。AddWindowListener(new WindowAdapter(){public void windowclosing(windowevent e){if(isstart){closeServer(); // close system} system.exit(0); // exit program}}); // event txt_message.addActionListener(new ActionListener(){public void ActionPerformed(ActionEvent e){send();}}); // event btn_send.addActionListener(new ActionListener(){public void ActionPerformed(ActionEvent Arg0){send();}}); // event btn_start.AddActionListener(new ActionListener(){public void ActionPerformed(ActionEvent e){if(isstart){joptionpane.showmessageialog(frame、 "サーバーはすでにスタートアップ状態にあります。 {max = integer.parseint(txt_max.gettext())} {"intection <= 0) 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); }}}); // event btn_stop.addactionlistener(new ActionListener(){public void ActionPerformed(ActionEvent e){if(!isstart){joptionpane.showmessageialog(frame、 "サーバーはまだ起動していません、停止する必要はありません! BTN_START.SECH.SETENABLED(True); joptionpane.showmessageialog(frame、 "サーバーが停止したときに例外が発生しました!"、 "error"、joptionpane.error_message); } //サーバーを開始しますpublic void serverStart(int max、int port)throws java.net.bindexception {try {clients = new ArrayList <ClientThread>(); Serversocket = new Serversocket(port); serverThread = new ServerThread(Serversocket、Max); serverthread.start(); isstart = true; } catch(bindexception e){isstart = false;新しいbindexception( "ポート番号が占有されている、変更してください!"); } catch(例外E1){e1.printstacktrace(); isstart = false;新しいbindexception( "Start Server Exception!"); }} // serverを閉じる@suppresswarnings( "deprecation")public void closeServer(){try {if(serverthread!= null)serverthread.stop(); //(int i = clients.size()-1; i> = 0; i-){// close close close close spreads.size() - 1; i> = 0; i-) clients.get(i).getWriter()。println( "close"); clients.get(i).getWriter()。flush(); //リソースクライアントをリリースします。get(i).stop(); //クライアントにサービスを提供するこのスレッドを停止します。 clients.get(i).writer.close(); clients.get(i).socket.close(); clients.remove(i); } if(serversocket!= null){serversocket.close(); // server-side connectionを閉じて} listmodel.removeallelements(); //ユーザーリストをクリアisstart = false; } catch(ioexception e){e.printstacktrace(); isstart = true; }} //バルクサーバーメッセージpublic void sendservermessage(string message){for(int i = clients.size() - 1; i> = 0; i--){clients.get(i).getWriter()。println( "server:" + message + "(複数の送信)"); clients.get(i).getWriter()。flush(); }} //サーバースレッドクラスServerThread拡張スレッド{private Serversocket Serversocket; Private int max; //人の上部数//サーバースレッドのメソッドの構築public serverthread(Serversocket Serversocket、int max){this.serversocket = serversocket; this.max = max; } public void run(){while(true){//クライアントリンクを待ってくださいtry {socket socket = serversocket.accept(); if(clients.size()== max){// bufferedreader r = new BufferedReader(new inputstreamReader(socket.getinputStream()))に到達した場合。 printWriter w = new PrintWriter(socket .getOutputStream()); //クライアント文字列から基本的なユーザー情報を受信しますinf = r.readline(); stringtokenizer st = new StringTokenizer(inf、 "@"); user user = new user(St.NextToken()、St.NextToken()); //フィードバック接続の成功情報w.println( "max@server:sorry、" + user.getname() + user.getip() + "、サーバー上のオンラインの人数が上限に達しました。後で接続してみてください!"); w.flush(); //リソースR.Close(); w.close(); socket.close();続く; } clientThread Client = new ClientThread(Socket); client.start(); //このクライアントサービスクライアントのスレッドを起動します。add(client); listmodel.addelement(client.getuser()。getname()); //オンラインリストContentarea.Append(client.getuser()。getName() + client.getUser()。getIp() + "online!/r/n"); } catch(ioexception e){e.printstacktrace(); }}}}}} //クライアントクラスにサービスを提供するスレッドclientthreadを拡張するスレッド{private socket socket;プライベートバッファレッドリーダー。プライベートプリントライターライター。プライベートユーザーユーザー; public bufferedreader getReader(){return reader; } public printwriter getWriter(){return Writer; } public user getUser(){return user; } //クライアントスレッドのコンストラクターpublic clientthread(socket socket){try {this.socket = socket; reader = new BufferedReader(new inputStreamReader(socket .getInputStream())); writer = new PrintWriter(socket.getOutputStream()); //クライアントの文字列から基本的なユーザー情報を受信inf = reader.readline(); stringtokenizer st = new StringTokenizer(inf、 "@"); user = new user(St.NextToken()、St.NextToken()); //フィードバック接続成功情報writer.println(user.getname() + user.getip() + "サーバーに正常に接続!"); writer.flush(); //現在のオンラインユーザー情報へのフィードバックif(clients.size()> 0){string temp = ""; for(int i = clients.size() - 1; i> = 0; i-){temp + =(clients.get(i).getuser()。getname() + "/" + clients .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( "add@" + user.getName() + user.getip()); clients.get(i).getWriter()。flush(); }} catch(ioexception e){e.printstacktrace(); }} @suppresswarnings( "deprecation")public void run(){//処理のためにクライアントから継続的にメッセージを受信します。文字列メッセージ= null; while(true){try {message = reader.readline(); //クライアントメッセージを受信するif(message.equals( "close"))// offline command {contentarea.append(this.getuser()。getname() + this.getuser()。 //リソースreader.close()を切断してリリースします。 writer.close(); socket.close(); //ユーザーのオフラインコマンドをすべてのオンラインユーザーに送信します。 clients.get(i).getWriter()。flush(); } listmodel.removeElement(user.getName()); //オンラインリストを更新//このクライアントサービススレッドを(int i = clients.size() - 1; i> = 0; i-){if(clients.get().getuser(i).getuser(i).getuser(){clientshread temp = clients.get(i); clients.remove(i); //このユーザーのサービススレッドtemp.stop(); //このサービススレッドのreturnを停止します。 }}} else {dispatchermessage(message); // forward message}} catch(ioexception e){e.printstacktrace(); }}}} //フォワードメッセージpublic void dispatchermessage(string message){stringtokenizer stringtokenizer = new StringTokenizer(message、 "@"); string source = stringtokenizer.nexttoken();文字列所有者= stringtokenizer.nexttoken(); string content = stringtokenizer.nexttoken(); message = source + ":" + content; contentarea.append(message + "/r/n"); if(ander.equals( "all")){// bulk for(int i = clients.size() - 1; i> = 0; i-){clients.get(i).getwriter()。println(message + "(multive send)"); clients.get(i).getWriter()。flush(); }}}}}}}client_more.java
Import java.awt.borderlayout; Import java.awt.color; Import java.awt.gridlayout; Import java.awt.toolkit; Import java.awt.event.actionevent; Import java.awt.event.event.actionlistener; Import Java.awt.event.windowadapter; java.awt.event.windowevent; import java.io.bufferedreader; Import java.io.ioexception; Impate java.io.inputStreamReader; Import java.net.socket; import java.util.hashmap; Import java.util.miped javax.swing.DefaultListModel;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JList;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.jsplitpane; Import javax.swing.jtextarea; import javax.swing.jtextfield; Import javax.swing.border.titledborder; public class client_more {private jframe frame;プライベートJLISTユーザーリスト。 Private JTextarea Textarea;プライベート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;プライベートjsplitpaneセンタースプリット。プライベートDefaultListModel ListModel; private boolean isconnected = false;プライベートソケットソケット。プライベートプリントライターライター。プライベートバッファレッドリーダー。 Private MessageThread Messagethread; //メッセージの受信を担当するスレッドプライベートマップ<String、user> onlineUsers = new Hashmap <string、user>(); //すべてのオンラインユーザー//メインメソッド、プログラムエントリPublic static void main(String [] args){new Client_more(); } // public void send(){if(!isconnected){joptionpane.showmessageialog(frame、 "サーバーはまだ接続されていないので、メッセージを送信できません!」、「エラー」、joptionpane.error_message);戻る; } string message = textfield.getText()。trim(); if(message == null || message.equals( "")){joptionpane.showmessageialog(frame、 "message na couns each!"、 "error"、joptionpane.error_message);戻る; } sendMessage(frame.getTitle() + "@" + "all" + "@" + message); textfield.settext(null); } // constructor public client_more(){textarea = new jtextarea(); textarea.setedable(false); textarea.setforeground(color.blue); textfield = new jtextfield(); txt_port = new jtextfield( "6666"); txt_hostip = new jtextfield( "127.0.0.1"); txt_name = new jtextfield( "wu chengqian"); btn_start = new jbutton( "connection"); btn_stop = new jbutton( "disconnect"); btn_send = new jbutton( "send"); listModel = new DefaultListModel(); userlist = new Jlist(listmodel); northpanel = new JPanel(); northpanel.setlayout(new gridlayout(1、7)); northpanel.add(new Jlabel( "Port")); northpanel.add(txt_port); northpanel.add(new Jlabel( "Server IP")); northpanel.add(txt_hostip); northpanel.add(new Jlabel( "name")); northpanel.add(txt_name); northpanel.add(btn_start); northpanel.add(btn_stop); northpanel.setborder(new Titledborder( "Connection Information")); rightscroll = new jscrollpane(textarea); rightscroll.setborder(new Titledborder( "メッセージ表示領域")); leftscroll = new JScrollpane(userlist); Leftscroll.setborder(new Titledborder( "オンラインユーザー")); southpanel = new jpanel(new borderlayout()); southpanel.add(textfield、 "center"); southpanel.add(btn_send、 "east"); Southpanel.setborder(new Titledborder( "write message")); centersplit = new jsplitpane(jsplitpane.horizontal_split、leftscroll、rightscroll); centersplit.setDividerLocation(100); frame = new JFrame( "Client"); // 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()。width; int screen_height = toolkit.getDefaultToolkit()。getScreensize()。height; frame.setlocation((screen_width -frame.getWidth()) / 2、(screen_height -frame.getheigh() / 2); frame.setVisible(true); //テキストボックスにEnterを押すと、メッセージtextfield.adcraptionlistener(new ActionListener(){public void ActionPerformed(actionEvent arg0){send();}}); // event BTN_SEND.ADDACTIONLISTENER(new ActionListener(){public void ActionPerformed(ActionEvent e){send();}}); // event btn_start.AddActionListener(new ActionListener(){public void actionPerformed(actionEvent e){int port; if(isConnected){joptionpane.showmessageialog(frame」 = parseint() hostip.equals( ""){nect connectserver(flag == connectserver(false); joptionpane.showmessageialog(frame、exc.getmessage()、 "error"、joptionpane.error_message); // event btn_stop.addaftionlistener(new ActionListener(){public void actionPerformed(actionEvent e){if(!isConnected){joptionpane.showmessageialog(frame、frame、 "既に切断された状態にあります。 boolean flag = closeConnection(); joptionpane.error_message); //ウィンドウフレームを閉じるとき。AddWindowListener(new WindowAdapter(){public void windowclosing(windowevent e){if(isConnected){closeConnection(); // connection} system.exit(0); // exitプログラム}}); }/ ** * serverに接続 * * @param port * @param Hostip * @param name */ public boolean connectserver(int port、string hostip、string name){//サーバーへの接続{socket = new socket(hostip、port); reader = new BufferedReader(new inputStreamReader(socket .getInputStream())); //クライアントユーザー(ユーザー名とIPアドレス)の基本情報を送信するsendmessage(name + "@" + socket.getLocalAddress()。toString()); //スレッドを開き、メッセージを受信しますmesagethread = new Messagethread(Reader、Textarea); messagethread.start(); isconnected = true; //はtrueを返すために接続されています。 } catch(Exception e){textarea.append( "ポート番号を備えたサーバー:" +ポート + "IPアドレス:" + HOSTIP + "failed!" + "/r/n"); isConnected = false; //接続されていないことにfalseを返します。 }} / ** *メッセージを送信 * * @paramメッセージ * / public void sendmessage(string message){writer.println(message); writer.flush(); }/ ***クライアントは接続を積極的に閉じます*/ @suppresswarnings( "deprecation")public synchronized closeconnection(){try {sendmessage( "close"); // server messagethread.stop(); } if(writer!= null){writer.close(); } if(socket!= null){socket.close(); } isConnected = false; trueを返します。 } catch(ioexception e1){e1.printstacktrace(); isconnected = true; falseを返します。 }} //メッセージを絶えず受信するスレッドクラスMessageThread拡張スレッド{private bufferedreader reader; Private JTextarea Textarea; //メッセージスレッドを受信する方法の構築public messagethread(bufferedreader reader、jtextarea textarea){this.reader = reader; this.textarea = textarea; } //接続を受動的に閉じるpublic synchronized void closecon()throws exception {//ユーザーlistmodel.removealLelements(); //接続を受動的に閉じてリソースをリリースするif(reader!= null){reader.close(); } if(writer!= null){writer.close(); } if(socket!= null){socket.close(); } isConnected = false; //ステータスを変更して切断する} public void run(){string message = ""; while(true){try {message = reader.readline(); stringtokenizer stringtokenizer = new StringTokenizer(message、 "/@"); string command = stringtokenizer.nexttoken(); // command if(command.equals( "close"))// server closht command {textarea.append( "server closing!/r/n"); closecon(); //接続を受動的に閉じますreturn; // end thread} else if(command.equals( "add")){//一部のユーザーはオンラインリスト文字列username = ""を更新しています文字列userip = ""; if((username = stringtokenizer.nexttoken())!= null &&(usertokenizer.nexttoken()!= null){user user = new user(username、userip); OnlineUsers.put(username、user); listmodel.addelement(username); }} else if(command.equals( "delete")){//一部のユーザーはオンラインリスト文字列username = stringtokenizer.nexttoken();ユーザーユーザー=(ユーザー)OnlineUsers.get(username); OnlineUsers.Remove(user); listmodel.removeElement(username); } else if(command.equals( "userlist")){//オンラインユーザーリストint size = integer .parseint(stringtokenizer.nexttoken());文字列username = null;文字列userip = null; for(int i = 0; i <size; i ++){username = stringtokenizer.nexttoken(); userip = stringtokenizer.nexttoken(); user user = new user(username、userip); OnlineUsers.put(username、user); listmodel.addelement(username); }} else if(command.equals( "max")){//人数は上限項に達しました。 closecon(); //接続を受動的に閉じますjoptionpane.showmessageialog(frame、 "サーバーバッファーはいっぱいです!"、 "error"、joptionpane.error_message); return; // end thread} else {//通常のメッセージtextarea.append(message + "/r/n"); }} catch(ioexception e){e.printstacktrace(); } catch(Exception e){e.printstacktrace(); }}}}}上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。