在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
有6个模块 1.用户登录 2.两两私聊 3.群发消息 4.退出登录 5.关闭服务器 6.文件传输
一、用户登录 服务器端: 二、两两私聊 三、群聊 四、用户退出连接 3、处理下线用户信息:DEL|username 五、服务器关闭 2、关闭ClientChat
2、遍历Arraylist将其中的每一个SocketChat关闭 六、文件传输 客户端: //2创建文件传输的服务器,与服务器接通 //3组织文件传输交互协议进行传输 //FILETRANS|sendername|recname|文件名|文件长度|IP|Port 处理服务器转发的内容,处理该内容确认是接收还是拒收,如果接收,建立连接通道接收文件(即开启fileRec线程) 服务器端: 接收发来的消息串,提取发送者+接收者+发送内容+传送文件的IP和Port 进行转发 服务器收到交互协议:FILECANCEL|拒收者|被拒收者 重新组织交互协议FILECANCELReturn|拒收者 要通知被拒收者,被拒收的消息
群发的流程图比较简单就没有画
六、文件传输
package rjxy.lkl.Client; import java.io.*; import java.net.*; public class ClientChat extends Thread { Socket socket; BufferedReader br = null; PrintWriter pw = null; String UserName; public ClientChat(Socket socket, String userName) { this.socket = socket; UserName = userName; try { br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8")); pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter( socket.getOutputStream(), "UTF-8"))); } catch (Exception e) { e.printStackTrace(); } //约定一个登录的交互协议Login|username sendMSG("Login|"+UserName); } public void sendMSG(String str){ pw.println(str); pw.flush(); } //断开socket连接 public void closeChat(){ try { if(socket!=null) socket.close(); } catch (Exception e) { e.printStackTrace(); } } //处理服务器发过来的在线用户List ,交互协议为:USERLISTS|user1_user2_user3 public void run() { try { String str = ""; while((str = br.readLine())!=null){ System.out.println("---"+str+"---"); String comms[] = str.split("[|]"); if(comms[0].equals("USERLISTS")){ String users[] = comms[1].split("_"); ClientMG.getClientMG().addItems(users); } else if(comms[0].equals("ADD")){ ClientMG.getClientMG().addItem(comms[1]); } else if(comms[0].equals("MsgReturn")){ //"MsgReturn|"+sender+"|"+msg String sender = comms[1]; String msg = comms[2]; ClientMG.getClientMG().setLog("【"+sender+"】:"); ClientMG.getClientMG().setLog(msg); } else if(comms[0].equals("DEL")){ //交互协议为:"DEL|"+UserName String sUser = comms[1]; ClientMG.getClientMG().removeItem(sUser); ClientMG.getClientMG().setLog(sUser+"已下线"); } else if(comms[0].equals("CLOSE")){ ClientMG.getClientMG().setLog("服务器已关闭"); //关闭ClientChat ClientMG.getClientMG().getClientChat().closeChat(); //清空在线用户列表 ClientMG.getClientMG().clearItems(); } else if(comms[0].equals("FILETRANS")){ //"FILETRANS|"+sender+"|"+sFname+"|"+finfo.length()+"|"+IP+"|"+Port String sender = comms[1]; String fileName = comms[2]; int filelen = Integer.parseInt(comms[3]); String sIP = comms[4]; int port = Integer.parseInt(comms[5]); //调用ClientMG中的接收文件的方法 ClientMG.getClientMG().recFile(sender, fileName, filelen, sIP, port); } else if(comms[0].equals("FILECANCEL")){ ClientMG.getClientMG().cancelFileTrans(); } else if (comms[0].equals("FILECANCELReturn")){ //FILECANCELReturn|拒收者A ClientMG.getClientMG().setLog(comms[1]+"取消了传输。。。"); } } } catch (Exception e) { e.printStackTrace(); }finally { try { if (br != null) br.close(); if (pw != null) pw.close(); if (socket != null) socket.close(); } catch (Exception e2) { e2.printStackTrace(); } } } }
package rjxy.lkl.Client; import java.awt.BorderLayout; public class ClientForm extends JFrame { private JPanel contentPane; public JPanel panel; public JLabel lblIp; public JTextField txtIP; public JLabel label_1; public JTextField txtPort; public JButton btnLogin; public JButton btnExit; public JPanel panel_1; public JButton btnSend; Socket socket; BufferedReader br=null; PrintWriter pw=null; public JScrollPane scrollPane; public JTextArea txtLog; public JScrollPane scrollPane_1; public JTextArea txtSend; public JLabel label; public JTextField txtUser; public JScrollPane scrollPane_2; public JList lOnlines; DefaultListModel<String> items=new DefaultListModel<String>(); public JButton sendToAll; public JButton FileTranbutton; public JProgressBar FileprogressBar; /** * Launch the application. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { ClientForm frame = new ClientForm(); frame.setVisible(true); ClientMG.getClientMG().setClientForm(frame); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the frame. */ public ClientForm() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 513, 583); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); contentPane.setLayout(null); panel = new JPanel(); panel.setLayout(null); panel.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "\u767B\u5F55\u4FE1\u606F", TitledBorder.LEADING, TitledBorder.TOP, null, null)); panel.setBounds(11, 10, 476, 64); contentPane.add(panel); lblIp = new JLabel("IP:"); lblIp.setHorizontalAlignment(SwingConstants.RIGHT); lblIp.setBounds(10, 19, 35, 31); panel.add(lblIp); txtIP = new JTextField(); txtIP.setText("10.12.50.10"); txtIP.setColumns(10); txtIP.setBounds(55, 22, 97, 24); panel.add(txtIP); label_1 = new JLabel("\u7AEF\u53E3:"); label_1.setHorizontalAlignment(SwingConstants.RIGHT); label_1.setBounds(154, 19, 35, 31); panel.add(label_1); txtPort = new JTextField(); txtPort.setText("8899"); txtPort.setColumns(10); txtPort.setBounds(190, 21, 35, 26); panel.add(txtPort); btnLogin = new JButton("\u767B\u5F55"); btnLogin.addActionListener(new BtnLoginActionListener()); btnLogin.setBounds(337, 22, 65, 25); panel.add(btnLogin); btnExit = new JButton("\u9000\u51FA"); btnExit.addActionListener(new BtnExitActionListener()); btnExit.setBounds(401, 22, 65, 25); panel.add(btnExit); label = new JLabel("\u7528\u6237\u540D:"); label.setHorizontalAlignment(SwingConstants.RIGHT); label.setBounds(228, 19, 50, 31); panel.add(label); txtUser = new JTextField(); txtUser.setText("visiter"); txtUser.setColumns(10); txtUser.setBounds(281, 22, 50, 26); panel.add(txtUser); panel_1 = new JPanel(); panel_1.setLayout(null); panel_1.setBorder(new TitledBorder(new LineBorder(new Color(184, 207, 229)), "\u64CD\u4F5C", TitledBorder.LEADING, TitledBorder.TOP, null, null)); panel_1.setBounds(10, 414, 477, 121); contentPane.add(panel_1); btnSend = new JButton("\u53D1\u9001\u6D88\u606F"); btnSend.addActionListener(new BtnSendActionListener()); btnSend.setBounds(357, 82, 110, 23); panel_1.add(btnSend); scrollPane_1 = new JScrollPane(); scrollPane_1.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); scrollPane_1.setBounds(10, 24, 457, 48); panel_1.add(scrollPane_1); txtSend = new JTextArea(); scrollPane_1.setViewportView(txtSend); sendToAll = new JButton("\u7FA4\u53D1\u6D88\u606F"); sendToAll.addActionListener(new ButtonActionListener()); sendToAll.setBounds(254, 82, 93, 23); panel_1.add(sendToAll); FileTranbutton = new JButton("\u4F20\u8F93\u6587\u4EF6"); FileTranbutton.addActionListener(new ButtonActionListener_1()); FileTranbutton.setBounds(10, 82, 81, 23); panel_1.add(FileTranbutton); FileprogressBar = new JProgressBar(); FileprogressBar.setBounds(98, 92, 146, 8); panel_1.add(FileprogressBar); scrollPane = new JScrollPane(); scrollPane.setBorder(new TitledBorder(null, "\u804A\u5929\u8BB0\u5F55", TitledBorder.LEADING, TitledBorder.TOP, null, null)); scrollPane.setBounds(11, 84, 309, 332); contentPane.add(scrollPane); txtLog = new JTextArea(); scrollPane.setViewportView(txtLog); scrollPane_2 = new JScrollPane(); scrollPane_2.setBorder(new TitledBorder(null, "\u5728\u7EBF\u7528\u6237", TitledBorder.LEADING, TitledBorder.TOP, null, null)); scrollPane_2.setBounds(323, 83, 164, 332); contentPane.add(scrollPane_2); lOnlines = new JList(items); scrollPane_2.setViewportView(lOnlines); } //登录 private class BtnLoginActionListener implements ActionListener { public void actionPerformed(ActionEvent arg0) { String ip = txtIP.getText().trim(); int port = Integer.parseInt(txtPort.getText().trim()); String socketname = txtUser.getText().trim(); ClientMG.getClientMG().connect(ip, port, socketname); } } //发送信息 private class BtnSendActionListener implements ActionListener { public void actionPerformed(ActionEvent arg0) { //选中要聊天的用户 String sendUsername = null; if(lOnlines.getSelectedIndex()>=0){ //得到用户选择的名称 String targetUsername = lOnlines.getSelectedValue().toString(); System.out.println(targetUsername); //发送者的名称 sendUsername = txtUser.getText().trim(); //消息体 String sMSG = txtSend.getText(); //交互协议 "MSG|"+sendUsername+"|"+targetUsername+"|"+sMSG //包装后的消息发送出去 String strSend = "MSG|"+sendUsername+"|"+targetUsername+"|"+sMSG; System.out.println(strSend); ClientMG.getClientMG().getClientChat().sendMSG(strSend); ClientMG.getClientMG().setLog("I send To "+targetUsername+":"); ClientMG.getClientMG().setLog(sMSG); //清空发送消息框 txtSend.setText(""); } } } //推出操作 private class BtnExitActionListener implements ActionListener { public void actionPerformed(ActionEvent arg0) { //组织推出交互协议"OFFLINE|"+username String sendMSG = "OFFLINE|"+txtUser.getText().trim(); ClientMG.getClientMG().getClientChat().sendMSG(sendMSG); //断开与服务器的socket连接 ClientMG.getClientMG().getClientChat().closeChat(); ClientMG.getClientMG().clearItems(); //清空列表 } } private class ButtonActionListener implements ActionListener { public void actionPerformed(ActionEvent e) { //发送者的名称 String sendUsername = txtUser.getText().trim(); //消息体 String sMSG = txtSend.getText(); //交互协议 "MSG|"+sendUsername+"|"+targetUsername+"|"+sMSG //包装后的消息发送出去 String strSend = "MSG|"+sendUsername+"|ALL|"+sMSG; System.out.println(strSend); //协议为:"MSG|"+sendUsername+"|ALL|"+msg ClientMG.getClientMG().getClientChat().sendMSG(strSend); txtSend.setText(""); } } //传输文件 private class ButtonActionListener_1 implements ActionListener { public void actionPerformed(ActionEvent e) { //1从本地选中一个文件,获取其文件相关信息(文件名,文件长度) //2创建文件传输的服务器,与服务器接通 //3组织文件传输交互协议进行传输 //FILETRANS|sendername|recname|文件名|文件长度|IP|Port File finfo = null; //用于文件选择的对象jFileChooser JFileChooser jFileChooser = new JFileChooser(); int result = jFileChooser.showOpenDialog(null); if(result==JFileChooser.APPROVE_OPTION){ finfo = new File(jFileChooser.getSelectedFile().getAbsolutePath()); String sFname = finfo.getName(); //在用户列表中选择目标用户 if(lOnlines.getSelectedIndex()!=-1){ String sTarget = lOnlines.getSelectedValue().toString();//得到目标用户 String sender = txtUser.getText().trim(); //得到新开服务器的IP+Port String IPandPort = ClientMG.getClientMG().CreateFileTranServer(finfo); //组织交互协议串,然后发送 FILETRANS+发送者+目标用户+文件名+文件的长度+IP和端口号 String strSend = "FILETRANS|"+sender+"|"+sTarget+"|"+sFname+"|"+finfo.length()+"|"+IPandPort; ClientMG.getClientMG().getClientChat().sendMSG(strSend); } } } } } package rjxy.lkl.Client; import java.io.File; import java.io.IOException; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; import javax.swing.JOptionPane; public class ClientMG { //实现管理类的单例化 private static final ClientMG clientMG = new ClientMG(); public ClientMG() { } public static ClientMG getClientMG(){ return clientMG; } //操作图形化界面 ClientForm cWin; ClientChat cChat; public void setClientForm(ClientForm cf){ cWin = cf; } // 设置界面中的消息记录 public void setLog(String str){ cWin.txtLog.append(str+"\r\n"); } public ClientChat getClientChat(){ return cChat; } //新上线的用户添加到JList中 public void addItem(String username){ cWin.items.addElement(username); } public void addItems(String [] sItems){ for (String username : sItems) { addItem(username); } } //一旦断开连接,清空JList中的用户 //清空单个 public void removeItem(String str){ cWin.items.removeElement(str); } //清空所有 public void clearItems(){ cWin.items.clear(); } public void connect(String IP,int port,String Username){ try { Socket socket = new Socket(IP,port); ClientMG.getClientMG().setLog("已连接到服务器 "); cChat = new ClientChat(socket,Username); cChat.start(); } catch (Exception e) { e.printStackTrace(); } } FileListener filelistener; //创建文件传输的服务器 public String CreateFileTranServer(File file){ try { ServerSocket server = new ServerSocket(8881); String IP = InetAddress.getLocalHost().getHostAddress(); filelistener = new FileListener(server,file); filelistener.start(); return IP+"|"+8881; } catch (Exception e) { e.printStackTrace(); } return ""; } //接收文件 public void recFile(String sender,String fName,int len,String IP,int port){ //文件名|文件长度|IP|Port //4判断是否要接收? JOptionPane->confirm //5同意接收,连接服务器进行文件传输 //6拒绝接收,向服务器发回拒接接收的消息:FILECANCEL|sendername|recname JOptionPane msg = new JOptionPane(); int result = msg.showConfirmDialog(null, sender+"发送文件【"+fName+"】,\r\n是否接收?", "文件传输确认", JOptionPane.YES_NO_OPTION); if(result == JOptionPane.YES_NO_OPTION){ //确认接收 try { Socket socket = new Socket(IP,port); new fileRec(socket, fName, len).start(); } catch (Exception e) { e.printStackTrace(); } } else{ //如果拒收 FILECANCEL|FromUser|toUser,sender给我发消息,某某某拒绝了,就通知sender,某某某拒绝了你的文件传输 String strSend = "FILECANCEL|"+this.getClientChat().UserName+"|"+sender; this.getClientChat().sendMSG(strSend); this.setLog("您已拒接了"+sender+"的文件传输"); } } //对方取消文件传递 public void cancelFileTrans(){ filelistener.cancelFileTrans(); // this.setLog("对方取消了文件传输!!!"); } } package rjxy.lkl.Client; import java.io.*; import java.net.*; public class FileListener extends Thread { ServerSocket fserver; File filetrans; public FileListener(ServerSocket fserver, File filetrans) { this.fserver = fserver; this.filetrans = filetrans; } //取消传输 public void cancelFileTrans(){ if(fserver!=null){ try { fserver.close(); } catch (Exception e) { e.printStackTrace(); } } } public void run() { Socket sfile = null; DataInputStream dis = null; DataOutputStream dos = null; try { sfile = fserver.accept(); dis = new DataInputStream(new FileInputStream(filetrans)); dos = new DataOutputStream(sfile.getOutputStream()); //有关进度条属性的设置 ClientMG.getClientMG().cWin.FileprogressBar.setValue(0); ClientMG.getClientMG().cWin.FileprogressBar.setVisible(true); ClientMG.getClientMG().cWin.FileprogressBar.setMaximum((int)filetrans.length()); byte[] buff = new byte[1024]; int iread = 0; int len =0; while((iread=dis.read(buff, 0, 1024))!=-1){ dos.write(buff, 0, iread); //写文件是,是根据读出的大小进行写入的 len += iread; dos.flush(); // 写入流的同时,设置进度条的进度 ClientMG.getClientMG().cWin.FileprogressBar.setValue(len); } ClientMG.getClientMG().setLog("文件传输完毕!"); } catch (Exception e) { e.printStackTrace(); } finally { try { dos.close(); dis.close(); if(sfile!=null){sfile.close();} if(fserver!=null){fserver.close();} } catch (Exception e) { e.printStackTrace(); } } } } package rjxy.lkl.Client; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.net.*; public class fileRec extends Thread{ Socket socket; String sRecFilePath="D:\\"; String fileName; int fileLen; public fileRec(Socket socket, String fileName, int fileLen) { this.socket = socket; this.fileName = fileName; this.fileLen = fileLen; } public void run() { DataInputStream dis = null; DataOutputStream dos = null; //设置进度条属性 ClientMG.getClientMG().cWin.FileprogressBar.setValue(0); ClientMG.getClientMG().cWin.FileprogressBar.setVisible(true); ClientMG.getClientMG().cWin.FileprogressBar.setMaximum(fileLen); try { dis = new DataInputStream(socket.getInputStream()); dos = new DataOutputStream(new FileOutputStream(sRecFilePath+fileName)); byte[] buff = new byte[1024]; int iread = 0; int len = 0; while((iread=dis.read(buff, 0, 1024))!=-1){ dos.write(buff, 0, iread); len +=iread; ClientMG.getClientMG().cWin.FileprogressBar.setValue(len); dos.flush(); } ClientMG.getClientMG().setLog("文件接收完毕!"); } catch (Exception e) { e.printStackTrace(); } finally { try { dis.close(); dos.close(); if(socket!=null){ socket.close();} } catch (Exception e) { e.printStackTrace(); } } } } 服务器端代码: package rjxy.lkl.Server; import java.awt.BorderLayout; public class ServerForm extends JFrame { private JPanel contentPane; public JPanel panel; public JLabel label; public JTextField txtPort; public JButton btnStart; public JButton btnStop; public JScrollPane scrollPane; public JTextArea txtLog; ServerSocket server; ServerListener listener; volatile boolean serverFlag; /** * Launch the application. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { ServerForm frame = new ServerForm(); frame.setVisible(true); SocketMG.getsocketMG().setServerForm(frame); //窗体对象传入SocketMG中 } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the frame. */ public ServerForm() { setResizable(false); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 422, 520); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); contentPane.setLayout(null); panel = new JPanel(); panel.setBorder(new TitledBorder(null, "\u914D\u7F6E\u4FE1\u606F", TitledBorder.LEADING, TitledBorder.TOP, null, null)); panel.setBounds(0, 0, 406, 66); contentPane.add(panel); panel.setLayout(null); label = 全部评论
专题导读
热门推荐
阅读排行榜
|
请发表评论