Java多线程实现聊天客户端和服务器
程序员文章站
2024-03-12 22:42:57
本文实例为大家分享了java聊天室代码,供大家参考,具体内容如下
主要涉及知识
·java中gui程序的编写,包括事件监听机制。
·java的网络通信编程,ser...
本文实例为大家分享了java聊天室代码,供大家参考,具体内容如下
主要涉及知识
·java中gui程序的编写,包括事件监听机制。
·java的网络通信编程,serversocket,socket类的使用。
·java中多线程的编程,thread类,runnable接口的使用。
源代码
客户端
package project1; import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; import javax.swing.*; public class client { private jframe clientframe; private jlabel iplabel; private jlabel portlabel; private jlabel saylabel; private jlabel nicknamelabel; private jtextfield iptext; private jtextfield porttext; private jtextfield nicknametext; private jtextfield saytext; private jbutton connectbutton; private jbutton nicknamebutton; private jbutton saybutton; private jpanel jpanelnorth; private jpanel jpanelsouth0; private jpanel jpanelsouth1; private jpanel jpanelsouth2; private jtextarea clienttextarea; private jscrollpane scroller; private bufferedreader reader; private printwriter writer; private string nickname; public static void main(string args[]) { client aclient = new client(); aclient.startup(); } // 初始化组件 public client() { nickname = "客户端"; clientframe = new jframe(); jpanelnorth = new jpanel(); iplabel = new jlabel("服务器ip", jlabel.left); iptext = new jtextfield(10); portlabel = new jlabel("服务器端口", jlabel.left); porttext = new jtextfield(10); connectbutton = new jbutton("连接"); clienttextarea = new jtextarea(); scroller = new jscrollpane(clienttextarea); jpanelsouth0 = new jpanel(); jpanelsouth1 = new jpanel(); jpanelsouth2 = new jpanel(); nicknamelabel = new jlabel("昵称", jlabel.left); nicknametext = new jtextfield(nickname, 30); nicknamebutton = new jbutton("确认"); saylabel = new jlabel("消息", jlabel.left); saytext = new jtextfield(30); saybutton = new jbutton("确认"); } // 构建gui private void buildgui() { // 窗口的设置 clientframe.settitle("客户端"); clientframe.setdefaultcloseoperation(jframe.exit_on_close); clientframe.setsize(550, 550); // 北区的组件 jpanelnorth.add(iplabel); jpanelnorth.add(iptext); jpanelnorth.add(portlabel); jpanelnorth.add(porttext); jpanelnorth.add(connectbutton); clientframe.getcontentpane().add(borderlayout.north, jpanelnorth); // 中间的组件 clienttextarea.setfocusable(false); scroller.setverticalscrollbarpolicy(scrollpaneconstants.vertical_scrollbar_always); scroller.sethorizontalscrollbarpolicy(scrollpaneconstants.horizontal_scrollbar_never); clientframe.getcontentpane().add(borderlayout.center, scroller); // 南区的组件 jpanelsouth1.add(nicknamelabel); jpanelsouth1.add(nicknametext); jpanelsouth1.add(nicknamebutton); jpanelsouth2.add(saylabel); jpanelsouth2.add(saytext); jpanelsouth2.add(saybutton); jpanelsouth0.setlayout(new boxlayout(jpanelsouth0, boxlayout.y_axis)); jpanelsouth0.add(jpanelsouth1); jpanelsouth0.add(jpanelsouth2); clientframe.getcontentpane().add(borderlayout.south, jpanelsouth0); // 设置窗口可见 clientframe.setvisible(true); } // 客户端运行 public void startup() { buildgui(); // 接收服务器消息的线程 runnable incomingreader = new runnable() { @override public void run() { string message; try { while ((message = reader.readline()) != null) { clienttextarea.append(message + "\n"); } } catch (exception ex) { ex.printstacktrace(); } } }; // 监听connect按钮,实现服务器的连接 connectbutton.addactionlistener(new actionlistener() { @override public void actionperformed(actionevent e) { string aserverip = iptext.gettext(); string aserverport = porttext.gettext(); if (aserverip.equals("") || aserverport.equals("")) { joptionpane.showmessagedialog(clientframe, "请输入 完整的 ip和端口!"); } else { try { @suppresswarnings("resource") socket clientsocket = new socket(aserverip, integer.parseint(aserverport)); inputstreamreader streamreader = new inputstreamreader(clientsocket.getinputstream()); reader = new bufferedreader(streamreader); writer = new printwriter(clientsocket.getoutputstream()); clienttextarea.append("服务器已连接...\n"); thread readerthread = new thread(incomingreader); readerthread.start(); } catch (exception ex) { joptionpane.showmessagedialog(clientframe, "连接不上服务器!\n请确认 ip 和 端口 输入正确。"); } } } }); // 监听nickname,设置昵称 actionlistener nicknamelistener = new actionlistener() { @override public void actionperformed(actionevent e) { string atext = nicknametext.gettext(); if (!atext.equals("")) { nickname = atext; } } }; nicknamebutton.addactionlistener(nicknamelistener); nicknametext.addactionlistener(nicknamelistener); nicknametext.addfocuslistener(new focuslistener() { @override public void focusgained(focusevent e) { } @override public void focuslost(focusevent e) { string atext = nicknametext.gettext(); if (!atext.equals("")) { nickname = atext; } } }); // 发送消息到服务器 actionlistener saylistener = new actionlistener() { @override public void actionperformed(actionevent e) { string atext = saytext.gettext(); if (atext.equals("")) { joptionpane.showmessagedialog(clientframe, "内容不能为空!"); } else { try { writer.println(nickname + ":" + atext); writer.flush(); } catch (exception ex) { ex.printstacktrace(); } saytext.settext(""); } } }; saybutton.addactionlistener(saylistener); saytext.addactionlistener(saylistener); } }
服务器
package project1; import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; import java.util.arraylist; import java.util.iterator; import javax.swing.*; public class server { private jframe serverframe; private jlabel portlabel; private jlabel saylabel; private jlabel nicknamelabel; private jtextfield porttext; private jtextfield saytext; private jtextfield nicknametext; private jbutton startbutton; private jbutton saybutton; private jbutton nicknamebutton; private jpanel jpanelnorth; private jpanel jpanelsouth0; private jpanel jpanelsouth1; private jpanel jpanelsouth2; private jscrollpane scroller; private jtextarea servertextarea; private arraylist<printwriter> clientoutputstreams; private string nickname; public static void main(string[] args) { server aserver = new server(); aserver.startup(); } // 初始化组件 public server() { nickname = "服务器"; serverframe = new jframe(); jpanelnorth = new jpanel(); portlabel = new jlabel("端口", jlabel.left); porttext = new jtextfield(30); startbutton = new jbutton("开始"); servertextarea = new jtextarea(); scroller = new jscrollpane(servertextarea); nicknamelabel = new jlabel("昵称", jlabel.left); nicknametext = new jtextfield(nickname, 30); nicknamebutton = new jbutton("确认"); jpanelsouth0 = new jpanel(); jpanelsouth1 = new jpanel(); jpanelsouth2 = new jpanel(); saylabel = new jlabel("消息", jlabel.left); saytext = new jtextfield(30); saybutton = new jbutton("确认"); } // 构建gui private void buildgui() { // 窗口的设置 serverframe.settitle("服务器"); serverframe.setdefaultcloseoperation(jframe.exit_on_close); serverframe.setsize(550, 550); // 北区的组件 jpanelnorth.add(portlabel); jpanelnorth.add(porttext); jpanelnorth.add(startbutton); serverframe.getcontentpane().add(borderlayout.north, jpanelnorth); // 中间的组件 servertextarea.setfocusable(false); scroller.setverticalscrollbarpolicy(scrollpaneconstants.vertical_scrollbar_always); scroller.sethorizontalscrollbarpolicy(scrollpaneconstants.horizontal_scrollbar_never); serverframe.getcontentpane().add(borderlayout.center, scroller); // 南区的组件 jpanelsouth1.add(nicknamelabel); jpanelsouth1.add(nicknametext); jpanelsouth1.add(nicknamebutton); jpanelsouth2.add(saylabel); jpanelsouth2.add(saytext); jpanelsouth2.add(saybutton); jpanelsouth0.setlayout(new boxlayout(jpanelsouth0, boxlayout.y_axis)); jpanelsouth0.add(jpanelsouth1); jpanelsouth0.add(jpanelsouth2); serverframe.getcontentpane().add(borderlayout.south, jpanelsouth0); // 设置窗口可见 serverframe.setvisible(true); } // 服务器运行 public void startup() { buildgui(); // 监听start按钮,建立端口 actionlistener startlistener = new actionlistener() { @override public void actionperformed(actionevent e) { clientoutputstreams = new arraylist<printwriter>(); string aport = porttext.gettext(); if (aport.equals("")) { joptionpane.showmessagedialog(serverframe, "请输入正确的端口号!"); } else { try { // 等待客户端连接的线程 runnable serverrunnable = new runnable() { @override public void run() { serversocket serversocket; try { serversocket = new serversocket(integer.parseint(aport)); servertextarea.append("正在等待客户端连接...\n"); while (true) { socket clientsocket = serversocket.accept(); servertextarea.append("客户端已连接...\n"); printwriter writer = new printwriter(clientsocket.getoutputstream()); clientoutputstreams.add(writer); thread t = new thread(new clienthandler(clientsocket)); t.start(); } } catch (numberformatexception | ioexception e) { e.printstacktrace(); } } }; thread serverthread = new thread(serverrunnable); serverthread.start(); } catch (exception ex) { ex.printstacktrace(); } } } }; startbutton.addactionlistener(startlistener); porttext.addactionlistener(startlistener); // 监听nickname,设置昵称 actionlistener nicknamelistener = new actionlistener() { @override public void actionperformed(actionevent e) { string atext = nicknametext.gettext(); if (!atext.equals("")) { nickname = atext; } } }; nicknamebutton.addactionlistener(nicknamelistener); nicknametext.addactionlistener(nicknamelistener); nicknametext.addfocuslistener(new focuslistener() { @override public void focusgained(focusevent e) { } @override public void focuslost(focusevent e) { string atext = nicknametext.gettext(); if (!atext.equals("")) { nickname = atext; } } }); // 监听say按钮,发送消息 actionlistener saylistener = new actionlistener() { @override public void actionperformed(actionevent e) { string atext = saytext.gettext(); if (!atext.equals("")) { atext = nickname + ":" + atext; sendtoeveryclient(atext); servertextarea.append(atext + "\n"); saytext.settext(""); } else { joptionpane.showmessagedialog(serverframe, "内容不能为空!"); } } }; saybutton.addactionlistener(saylistener); saytext.addactionlistener(saylistener); } // 多客户端的线程 public class clienthandler implements runnable { bufferedreader breader; socket asocket; public clienthandler(socket clientsocket) { try { asocket = clientsocket; inputstreamreader isreader = new inputstreamreader(asocket.getinputstream()); breader = new bufferedreader(isreader); } catch (exception ex) { ex.printstacktrace(); } } @override public void run() { string message; try { while ((message = breader.readline()) != null) { sendtoeveryclient(message); servertextarea.append(message + "\n"); } } catch (exception ex) { ex.printstacktrace(); } } } // 发送消息给所有客户端的方法 private void sendtoeveryclient(string message) { iterator<printwriter> it = clientoutputstreams.iterator(); while (it.hasnext()) { try { printwriter writer = (printwriter) it.next(); writer.println(message); writer.flush(); } catch (exception ex) { ex.printstacktrace(); } } } }
gui运行截图:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。