基于Java Socket的局域网聊天系统
?實驗目標:
1、Java實現一個基于TCP/UDP的網絡聊天系統-添加UI和使用持久化技術
2、本系統的持久化技術是使用文件存儲,存放到一個excel表格中
3、本系統實現了一個服務器端-多線程監聽;客戶端可與服務器端實現通信--通信圖如下圖。
4、其中:本系統實現了局域網通信,如果需要使用本系統,請到通信配置處修改通信IP
項目已開源:?
?????????gitee: https://gitee.com/TangGarlic/socket-chat-system.git
? ? ? ? github:?https://github.com/TonyTang-dev/javaSocketChatSystem.git
如有改進需求和改進想法,可與作者聯系。
實現效果:
1、socket:socket叫套接字,由IP地址和端口號共同組成。每一條TCP 連接唯一地被通信兩端的兩個端點即兩個套接字所確定,形如:
2、端口號:即協議端口號,通常簡稱為端口(port),通信的終點是應用 進程,可以通過把端口想象成為通信的終點,因為只需要把傳送的報文交到目的主機的某一個合適的目的端口,剩下的工作即最后交付目的進程就由TCP完成。在協議棧層間的抽象的協議端口是軟件端口,而硬件端口是不同硬件設備進行交互的端口,而軟件端口是應用層的各種協議進程與傳輸實體進行層間交互的一種地址。端口用一個16位端口號進行標志,只具有本地意義,即端口號只是為了標志本計算機應用層中的各進程;在互聯網中,不同計算機的相同端口號沒有聯系。因此兩臺計算機中的進程要相互通信,不僅需要知道對方的IP地址以找到對方計算機,而且還要知道對方的端口號以找到對方計算機中的應用進程。 3、TCP:即傳輸控制協議,傳送的數據單位協議是TCP報文段,是一 種面向連接的協議,提供面向連接的服務,傳送的數據單位協議是TCP報文段,不提供廣播或多播服務;由于TCP要提供可靠的、面向連接的傳輸服務,因此不可避免地增加了許多的開銷,這不僅使協議數據單元的首部增大很多,還要占用許多的處理及資源。TCP報文段是在傳輸層抽象的端到端邏輯信道中傳送,是可靠的全雙工信道。但這樣的信道卻不知道究竟經過了那些路由器,而這些路由器也根本不知道上面的傳輸層是否建立了TCP連接。
4、UDP:即用戶數據報協議,傳輸的數據單位協議是用戶數據報,是 一種無連接協議,在傳輸數據之前不需要先建立連接,傳送的數據單位協議是UDP報文或用戶數據報;對方的傳輸層在收到UDP報文后不需要給出任何確認,雖然UDP不提供可靠交付,但在某些情況下UDP是一種最有效的工作方式。UDP用戶數據包與網絡層的IP數據報有很大差別主要是IP數據報要經過互聯網中許多路由器的存儲轉發,UDP用戶數據包是在傳輸層的端到端抽象的邏輯信道中傳送的。 5、注意:UDP傳輸是基于報文的,而TCP傳輸是面向字節流的,其中 TCP的字節流中的“流”是指流入或流出進程的字節序列,面向字節流的含義是雖然應用程序和TCP的交互是一次一個數據塊,但TCP把應用程序交下來的數據看成僅僅是一連串無結構的字節流。
實現: 1、因為目前還沒有直接連接公網IP的功能,我們采用的是基于局域 網的聊天系統。其中通過連接同一個路由器(本次使用一個手機移動熱點作為無線路由器),客戶端和服務端都連接至此局域網以實現物理組網。 2、我們對系統的設計為:客戶端各個端既是服務器又是客戶機,即 客戶端之間可以直接收發消息和傳輸文件,實現的一個端到端的系統;與此同時,為了解決客戶之間需要尋找陌生用戶和與陌生用戶建立通信的需求,我們搭建了一個服務器,供客戶端訪問服務端獲得陌生人信息,服務器下發信息到客戶端。客戶端之間的通信我們使用的是面向無連接的UDP通信,而客戶機與服務器之間的通信我們使用的是面向連接的TCP通信,建立的邏輯框圖如下:
3、我們采用的開發語言是Java程序設計語言,其中用于實現UDP通 信的算法,如下所示:
如圖所示,實現的是UDP的通信連接請求發送過程,標號1是我們實現的一個序列化類,用于存儲需要發送的信息如文本,文件等等;標號2是通過InetAddress來設置需要連接的用戶的IP地址,通過獲得port來設置對方的軟件端口,并通過socket發送出去,用戶接受的程序實現如下:
其中通過獲取輸入流并解析就可以得到傳輸的內容。同理,基于TCP通信的發送請求和接受內容實現如下所示(以訪問服務器為例):
我們采用的序列化發送類如下所示,其中Cmd是指自定義的一些識別代碼,例如以1024代表的是發送文本,對方接受到內容并解析得到Cmd是1024后就知道要接受文本;還分別存儲了己方賬號和對方賬號,便于雙方知道通信雙方的信息;其余變量類似,即存儲文件或文件名以及存儲發送的字節等等,最后一個向量存儲的是訪問服務器后得到的用戶信息。
服務端因為要訪問來自用戶的訪問,所以必須要實現多線程通信,所以我們加入了多線程編程(客戶端也實現了),每個用戶訪問服務器都會啟動一個線程來響應,線程體實現如下:
完成基本的框架搭建之后,為了增加系統的可視化性,增加了UI設計,提高用戶使用體驗感,便于用戶直接使用;同時,由于系統需要存儲用戶信息避免再次返回系統時好友信息丟失,我們采用文件存儲的方式來是實現數據持久化,即將用戶(好友)數據保存于文件中,通過讀寫文件實現數據保存,實現效果如下含文件表:(以好友列表為例)
報文發送和文件處理部分示例代碼,詳情查看代碼倉庫:
package ht.ui; //主窗口 import ht.bean.Account; import ht.cmd.Cmd; import ht.db.DBOper; import ht_.Send; import ht_.SendMsg;import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.FileDialog; import java.awt.Font; import java.awt.Image; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.ObjectInputStream; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Set; import java.util.Vector;import javax.swing.AbstractListModel; import javax.swing.DefaultListCellRenderer; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPasswordField; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JTabbedPane; //啟動線程 進入循環等到接收消息 public class MainUI extends JFrame implements MouseListener,ActionListener{/*** */private static final long serialVersionUID = 1L;private Account account,friendAccount;private JTabbedPane tab;private JLabel lblhead;//登陸后顯示的個人資料private JList<?> lstFriend;private JList<?> lstFamily;private JList<?> lstclassmate;private JList<?> lsthmd;private JButton btnFind;//查找好友按鈕private Vector<Account> vFriend,vFamily,vClassmate,vHmd,vAllDetail;private JPopupMenu pop;//彈出菜單private JMenu menu;private JMenuItem miChat,miLookInfo,miFriend,miFamily,miMate,miHmd,miDel;//聊天 查看資料 刪除好友 移動好友//創建哈希表保存所有在線用戶的窗口private LinkedHashMap<Integer,ChatUI> ht_ChatUsers;public MainUI(){}public MainUI(Account acc) throws IOException{this.account=acc;setTitle(acc.getNickName());//設置窗口標簽欄標題和頭像setIconImage(new ImageIcon(acc.getFace()).getImage());//獲取昵稱 備注 QQ號 個性簽名String str="";//備注不為空時,顯示備注不顯示昵稱if(!acc.getRemark().equals("")){str=acc.getRemark()+"(";}//備注為空時,顯示昵稱else {str=acc.getNickName()+"(";}str+=acc.getQqCode()+")"+acc.getSelfsign(); lblhead=new JLabel(str,new ImageIcon(acc.getFace()),JLabel.LEFT);add(lblhead,BorderLayout.NORTH);vFriend=new Vector<Account>();vFamily=new Vector<Account>();vClassmate=new Vector<Account>();vHmd=new Vector<Account>();vAllDetail=new Vector<Account>();lstFamily=new JList();lstFriend=new JList();lstclassmate=new JList();lsthmd=new JList();lstFriend.addMouseListener(this);lstFamily.addMouseListener(this);lstclassmate.addMouseListener(this);lsthmd.addMouseListener(this);refresh();//讀好友列表tab=new JTabbedPane();tab.add("好友",new JScrollPane(lstFriend));tab.add("家人",new JScrollPane(lstFamily));tab.add("同學",new JScrollPane(lstclassmate));tab.add("其他",new JScrollPane(lsthmd));add(tab);createMenu();btnFind=new JButton("查找/添加好友");add(btnFind,BorderLayout.SOUTH);btnFind.addActionListener(this);setSize(300,680);setVisible(true);setResizable(true);//得到屏幕寬度,設置窗口位置int width=Toolkit.getDefaultToolkit().getScreenSize().width-300;setLocation(width,50);setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);//監聽叉關閉this.addWindowListener(new WindowAdapter(){@Overridepublic void windowClosing(WindowEvent e) {//super.windowClosing(e); //To change body of overridden methods use File | Settings | File Templates.//這里寫你想實現的代碼,我只寫了一行printlnSystem.exit(0);}});//啟動消息接收線程new ReceThread().start();}class listmodel extends AbstractListModel{Vector dats;public listmodel(Vector dats){this.dats=dats;}//獲取行數public Object getElementAt(int index){Account user=(Account) dats.get(index);return user.getNickName().trim()+"【"+user.getQqCode()+"】";}//獲取長度public int getSize(){return dats.size();}}//獲取好友頭像class myfind extends DefaultListCellRenderer{Vector datas;public myfind(Vector datas){this.datas=datas;}public Component getListCellRendererComponent(JList list,Object value, int index, boolean isSelected,boolean cellHasFocus){Component c=super.getListCellRendererComponent(list,value,index,isSelected,cellHasFocus);if(index >=0 && index<datas.size()){Account user=(Account) datas.get(index);//根據列表中的好友在線狀態設置頭像if(user.getStatus()==1){setIcon(new ImageIcon(user.getFace()));}else{setIcon(new ImageIcon("face/bzx.png"));}setText(user.getNickName().trim()+"("+user.getQqCode()+")");}//設置字體顏色if(isSelected){setBackground(list.getSelectionBackground());setForeground(list.getSelectionForeground());}else{setBackground(list.getBackground());setForeground(list.getForeground());}setEnabled(list.isEnabled());setFont(list.getFont());setOpaque(true);return this;}}//創建菜單public void createMenu(){pop=new JPopupMenu();miChat=new JMenuItem("聊天");miLookInfo=new JMenuItem("查看資料");miFriend=new JMenuItem("移動到好友");miFamily=new JMenuItem("移動到家人");miMate=new JMenuItem("移動到同學");miHmd=new JMenuItem("移動到黑名單");miDel=new JMenuItem("刪除好友");miChat.addActionListener(this);miLookInfo.addActionListener(this);miFriend.addActionListener(this);miFamily.addActionListener(this);miMate.addActionListener(this);miHmd.addActionListener(this);miDel.addActionListener(this);pop.add(miChat);pop.add(miLookInfo);pop.add(miFriend);pop.add(miFamily);pop.add(miMate);pop.add(miHmd);pop.add(miDel);}//刷新界面public void refresh() throws IOException{vAllDetail=new DBOper().getAllInfo(account);//如果沒有用戶的情況下,直接結束函數if(vAllDetail==null) {//清楚之前所有的記錄vFriend.clear();vFamily.clear();vClassmate.clear();vHmd.clear();return;}//清楚之前所有的記錄vFriend.clear();vFamily.clear();vClassmate.clear();vHmd.clear();//把數據庫的最新數據分別放到對應的向量for(int i=0;i<vAllDetail.size();i++){Account a=vAllDetail.get(i);if(a.getGroupname().equals(Cmd.F_FRIEND)){vFriend.add(a);}else if(a.getGroupname().equals(Cmd.F_FAMILY)){vFamily.add(a);}else if(a.getGroupname().equals(Cmd.F_CLASSMATE)){vClassmate.add(a);}else if(a.getGroupname().equals(Cmd.F_HMD)){vHmd.add(a);}//暫時未做處理,直接顯示在好友欄vFriend.add(a);}//把向量放入List控件lstFriend.setModel(new listmodel(vFriend));//顯示資料lstFriend.setCellRenderer(new myfind(vFriend));//顯示頭像lstFamily.setModel(new listmodel(vFamily));//顯示資料lstFamily.setCellRenderer(new myfind(vFamily));//顯示頭像lstclassmate.setModel(new listmodel(vClassmate));//顯示資料lstclassmate.setCellRenderer(new myfind(vClassmate));//顯示頭像lsthmd.setModel(new listmodel(vHmd));//顯示資料lsthmd.setCellRenderer(new myfind(vHmd));//顯示頭像}@Overridepublic void mouseClicked(MouseEvent e) {if(e.getSource()==lstFriend){if(lstFriend.getSelectedIndex()==-1) {JOptionPane.showMessageDialog(null, "當前列表無好友", "提示", JOptionPane.PLAIN_MESSAGE);return;}friendAccount=(Account)vFriend.get(lstFriend.getSelectedIndex());//雙擊if(e.getClickCount()==2){// new ChatUI(account,friendAccount);findWin(friendAccount.getQqCode(),null);}//郵件if(e.getButton()==3){//好友被選中if(lstFriend.getSelectedIndex()>=0){pop.show(lstFriend, e.getX(), e.getY());}}}else if(e.getSource()==lstFamily){if(lstFamily.getSelectedIndex()==-1) {JOptionPane.showMessageDialog(null, "當前列表無好友", "提示", JOptionPane.PLAIN_MESSAGE);return;}friendAccount=(Account)vFamily.get(lstFamily.getSelectedIndex());//雙擊if(e.getClickCount()==2){//new ChatUI(account,friendAccount);findWin(friendAccount.getQqCode(),null);}//郵件if(e.getButton()==3){//被選中if(lstFamily.getSelectedIndex()>=0){pop.show(lstFamily, e.getX(), e.getY());}}}else if(e.getSource()==lstclassmate){if(lstclassmate.getSelectedIndex()==-1) {JOptionPane.showMessageDialog(null, "當前列表無好友", "提示", JOptionPane.PLAIN_MESSAGE);return;}friendAccount=(Account)vClassmate.get(lstclassmate.getSelectedIndex());//雙擊if(e.getClickCount()==2){// new ChatUI(account,friendAccount);findWin(friendAccount.getQqCode(),null);}//郵件if(e.getButton()==3){//被選中if(lstclassmate.getSelectedIndex()>=0){pop.show(lstclassmate, e.getX(), e.getY());}}}else if(e.getSource()==lsthmd){if(lsthmd.getSelectedIndex()==-1) {JOptionPane.showMessageDialog(null, "當前列表無好友", "提示", JOptionPane.PLAIN_MESSAGE);return;}friendAccount=(Account)vHmd.get(lsthmd.getSelectedIndex());//雙擊if(e.getClickCount()==2){//new ChatUI(account,friendAccount);findWin(friendAccount.getQqCode(),null);}//右擊if(e.getButton()==3){//被選中if(lsthmd.getSelectedIndex()>=0){pop.show(lsthmd, e.getX(), e.getY());}}}}@Overridepublic void mouseEntered(MouseEvent arg0) {// TODO Auto-generated method stub}@Overridepublic void mouseExited(MouseEvent arg0) {// TODO Auto-generated method stub}@Overridepublic void mousePressed(MouseEvent arg0) {// TODO Auto-generated method stub}@Overridepublic void mouseReleased(MouseEvent arg0) {// TODO Auto-generated method stub}@Overridepublic void actionPerformed(ActionEvent e) {if(e.getSource()==btnFind){try {new FindUI(account);} catch (IOException | ClassNotFoundException e1) {// TODO Auto-generated catch block e1.printStackTrace();}}else if(e.getSource()==miChat){// new ChatUI(account,friendAccount);findWin(friendAccount.getQqCode(),null);}else if(e.getSource()==miLookInfo){if(friendAccount!=null) new LookUsers(friendAccount);}else if(e.getSource()==miDel){try {new DBOper().delFriend(account, friendAccount.getQqCode());refresh();} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}try {refresh();} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}else if(e.getSource()==miFriend){try {new DBOper().moveFriend(account, friendAccount.getQqCode(),Cmd.F_FRIEND);} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}try {refresh();} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}else if(e.getSource()==miFamily){try {new DBOper().moveFriend(account, friendAccount.getQqCode(),Cmd.F_FAMILY);} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}try {refresh();} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}else if(e.getSource()==miMate){try {new DBOper().moveFriend(account, friendAccount.getQqCode(),Cmd.F_CLASSMATE);} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}try {refresh();} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}else if(e.getSource()==miHmd){}}//接收消息的線程class ReceThread extends Thread{public ReceThread(){//啟動線程時 創建保存窗口的哈希表ht_ChatUsers=new LinkedHashMap<Integer,ChatUI>();}public void run(){try {//自己端口接收數據DatagramSocket serverSocket=new DatagramSocket(account.getPort());//在自己端口接收數據//接收客戶端發來的信息存入pack包while(true){byte b[]=new byte[1024*70]; DatagramPacket pack=new DatagramPacket(b,b.length) ;//數據包serverSocket.receive(pack);//把字節數組轉換成SendMsg對象//pack.getLength()接收到的字節數ByteArrayInputStream bis=new ByteArrayInputStream(b,0,pack.getLength());//字節數組輸入流ObjectInputStream ois=new ObjectInputStream(bis);SendMsg msg=(SendMsg)ois.readObject();switch(msg.Cmd){case Cmd.CMD_ONLINE://接收上線通知refresh();break;case Cmd.CMD_OFFLINE://接收離線通知refresh();break;case Cmd.CMD_CHAT://接收聊天信息ChatUI chat=findWin(msg.selfAccount.getQqCode(),msg);//顯示窗口//獲取聊天消息chat.appendView(msg.selfAccount.getNickName(),msg.doc);break;case Cmd.CMD_DOUDONG://接收抖動信息chat=findWin(msg.selfAccount.getQqCode(),msg);//顯示窗口chat.shake();break;case Cmd.CMD_ADDFRIEND://添加好友String str=msg.selfAccount.getNickName()+"添加你為好友 ,請確認";SendMsg m=new SendMsg();m.friendAccount=msg.selfAccount;m.selfAccount=msg.friendAccount;//如果點擊確定按鈕就添加if(JOptionPane.showConfirmDialog(null,str,"添加好友",JOptionPane.OK_CANCEL_OPTION)==JOptionPane.OK_OPTION){//往朋友表中添加記錄new DBOper().addFriend(m.friendAccount, m.selfAccount.getQqCode());refresh();m.Cmd=Cmd.CMD_AFREEFRIEND;}else{m.Cmd=Cmd.CMD_REJECTFRIEND;}break;case Cmd.CMD_AFREEFRIEND://同意refresh();//刷新界面break;case Cmd.CMD_REJECTFRIEND://拒絕JOptionPane.showMessageDialog(null,msg.selfAccount.getNickName()+"拒接了你的好友請求");break; case Cmd.CMD_FILESEND://接受文件String str1=msg.selfAccount.getNickName()+"發送了文件"+msg.sFileName;int cmd=Cmd.CMD_FILESUCC;if(JOptionPane.showConfirmDialog(null,str1,"接收文件",JOptionPane.OK_CANCEL_OPTION)==JOptionPane.OK_OPTION){FileDialog dlg=new FileDialog(MainUI.this,"保存",FileDialog.SAVE);dlg.setFile(msg.sFileName);dlg.show();String sfilename=dlg.getDirectory()+"\\"+dlg.getFile();File file=new File(sfilename);if(!file.exists()){file.createNewFile();}FileOutputStream fos=new FileOutputStream(sfilename);fos.write(msg.b);fos.close();}else{cmd=Cmd.CMD_FILEFAILED;}SendMsg msg1=new SendMsg();msg1.selfAccount=msg.friendAccount;msg1.friendAccount=msg.selfAccount;msg1.Cmd=cmd;new Send().send(msg1);break;case Cmd.CMD_FILESUCC://回復接受成功JOptionPane.showMessageDialog(null,msg.selfAccount.getNickName()+"接受了文件");break;case Cmd.CMD_FILEFAILED://回復拒接JOptionPane.showMessageDialog(null,msg.selfAccount.getNickName()+"拒絕了文件");break;}}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();} }}//查找窗口是否存在,如果不存在則創建,存在則直接顯示信息在界面public ChatUI findWin(Integer qqcode,SendMsg msg){ChatUI chat=null;//查找窗口是否存在chat =ht_ChatUsers.get(qqcode);if(chat==null)//不存在則創建聊天窗口{if(msg==null)//雙擊或者右鍵打開窗口{chat=new ChatUI(account,friendAccount);}else//線程打開窗口{chat=new ChatUI(msg.friendAccount,msg.selfAccount);}//窗口加入哈希表ht_ChatUsers.put(qqcode,chat); }if(!chat.isVisible()){chat.show();}return chat; }//修改用戶狀態public void UpdateStatus(Account acc) throws IOException{int size=vAllDetail.size();for(int i=0;i<size;i++){Account a=vAllDetail.get(i);if(a.getQqCode()==acc.getQqCode()){a.setStatus(acc.getStatus());vAllDetail.set(i, a);break;}}refresh();} } package ht.db;import java.io.File; import java.io.FileOutputStream; import java.io.IOException;import java.util.Vector;import javax.swing.JOptionPane;import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFDataFormat; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook;import ht.bean.Account; import ht.cmd.Cmd;//進行數據庫操作的函數 public class DBOper {//所有值都放到account對象里去了 ,傳一個Account對象過來,注冊用戶的函數public boolean addUser(Account acc) throws IOException{boolean bok=false;HSSFWorkbook conn=new DBConn().getWrokbook();for (int sh=0;sh<2;sh++) {HSSFSheet sheet=conn.getSheetAt(sh);int index=sheet.getLastRowNum();HSSFRow row = sheet.getRow(index);if(row != null) {//檢查行是不是空index+=1;}try {HSSFRow currow = sheet.createRow((short)index);HSSFCellStyle textStyle = conn.createCellStyle();HSSFDataFormat format = conn.createDataFormat();// textStyle.setDataFormat(format.getFormat("@"));// cell.setCellStyle(textStyle);//設置單元格格式為"文本"// cell.setCellType(HSSFCell.CELL_TYPE_STRING);HSSFCell cell=null;//在row里建立新cell(單元格),參數為列號(第一列) //設置cell的整數類型的值cell=currow.createCell(0);cell.setCellValue(String.valueOf(acc.getQqCode())); //設置cell浮點類型的值cell.setCellType(HSSFCell.CELL_TYPE_STRING);cell=currow.createCell(1);cell.setCellValue(String.valueOf(acc.getNickName())); //設置cell字符類型的值cell.setCellType(HSSFCell.CELL_TYPE_STRING);cell=currow.createCell(2);cell.setCellValue(String.valueOf(acc.getPwd())); //設置cell布爾類型的值cell.setCellType(HSSFCell.CELL_TYPE_STRING);cell=currow.createCell(3);cell.setCellValue(String.valueOf(acc.getIpAddr())); //設置cell浮點類型的值cell.setCellType(HSSFCell.CELL_TYPE_STRING);cell=currow.createCell(4);cell.setCellValue(String.valueOf(acc.getPort())); //設置cell字符類型的值cell.setCellType(HSSFCell.CELL_TYPE_STRING);cell=currow.createCell(5);cell.setCellValue(String.valueOf(acc.getAge())); //設置cell布爾類型的值cell.setCellType(HSSFCell.CELL_TYPE_STRING);cell=currow.createCell(6);cell.setCellValue(String.valueOf(acc.getSex())); //設置cell浮點類型的值cell.setCellType(HSSFCell.CELL_TYPE_STRING);cell=currow.createCell(7);cell.setCellValue(String.valueOf(acc.getNation())); //設置cell字符類型的值cell.setCellType(HSSFCell.CELL_TYPE_STRING);cell=currow.createCell(8);cell.setCellValue(String.valueOf(acc.getStar())); //設置cell布爾類型的值cell.setCellType(HSSFCell.CELL_TYPE_STRING);cell=currow.createCell(9);if(String.valueOf(acc.getFace()).equals("")) {cell.setCellValue("face\3.jpg");}else {cell.setCellValue(String.valueOf(acc.getFace())); //設置cell浮點類型的值}cell.setCellType(HSSFCell.CELL_TYPE_STRING);cell=currow.createCell(10);cell.setCellValue(String.valueOf(acc.getRemark())); //設置cell字符類型的值cell.setCellType(HSSFCell.CELL_TYPE_STRING);cell=currow.createCell(11);cell.setCellValue(String.valueOf(acc.getSelfsign())); //設置cell布爾類型的值cell.setCellType(HSSFCell.CELL_TYPE_STRING);cell=currow.createCell(12);cell.setCellValue(String.valueOf(acc.getStatus())); //設置cell布爾類型的值cell.setCellType(HSSFCell.CELL_TYPE_STRING);FileOutputStream fileOut = new FileOutputStream("data.xls");conn.write(fileOut); fileOut.close();//狀態bok=true;}catch(Exception e){e.printStackTrace();}}return bok;}//判斷端口是否已經被占用public boolean isPort(int port) throws IOException{boolean bok=false;HSSFWorkbook conn=new DBConn().getWrokbook();try {for (int i=0;i<3;i++) {HSSFSheet sheet=conn.getSheetAt(i);int num=sheet.getLastRowNum();if(sheet.getRow(0)==null) {//第一行是空就代表沒有數據了,更不能用getCell了 // return false;continue;}for (int j=0;j<=num;j++) {HSSFRow row = sheet.getRow(j);if(String.valueOf(port).equals(String.valueOf(row.getCell(4).getStringCellValue()))) {return true;}}}}catch(Exception e){e.printStackTrace();}return bok;}//登錄函數,返回account對象public Account login(Account acc) throws IOException{HSSFWorkbook conn=new DBConn().getWrokbook();try {boolean flag1=false;int index=-1;HSSFSheet sheet=conn.getSheetAt(0);int num=sheet.getLastRowNum();if(sheet.getRow(0)==null) {return null;}for (int j=0;j<=num;j++) {HSSFRow row = sheet.getRow(j);if(String.valueOf(acc.getQqCode()).equals(String.valueOf(row.getCell(0).getStringCellValue()))&& String.valueOf(acc.getPwd()).equals(String.valueOf(row.getCell(2).getStringCellValue()))) {flag1=true;index=j;break;}}//ResultSet表示從數據庫中查詢到的返回結果if(flag1)//查到了賬號名跟密碼匹配的東西 已經登陸了{ //登陸成功,讀取用戶所有信息//修改狀態為在線(1)HSSFRow row = sheet.getRow(index);acc.setNickName(String.valueOf(row.getCell(1).getStringCellValue()));acc.setIpAddr(String.valueOf(row.getCell(3).getStringCellValue()));acc.setPort(Integer.parseInt(String.valueOf(row.getCell(4).getStringCellValue())));acc.setAge(Integer.parseInt(String.valueOf(row.getCell(5).getStringCellValue())));acc.setSex(String.valueOf(row.getCell(6).getStringCellValue()));acc.setNation(String.valueOf(row.getCell(7).getStringCellValue()));acc.setStar(String.valueOf(row.getCell(8).getStringCellValue()));acc.setFace(String.valueOf(row.getCell(9).getStringCellValue()));acc.setRemark(String.valueOf(row.getCell(10).getStringCellValue()));acc.setSelfsign(String.valueOf(row.getCell(11).getStringCellValue()));acc.setStatus(1);//修改對象值為1//修改數據庫中存儲狀態為上線modifyStatus(acc.getQqCode(),1);}}catch(Exception e){e.printStackTrace();}return acc;}//查找個人資料public Account findByQQcode (int qqcode) throws IOException{HSSFWorkbook conn=new DBConn().getWrokbook();HSSFSheet sheet=conn.getSheetAt(1);int num=sheet.getLastRowNum();if(sheet.getRow(0)==null) {return null;}Account acc=new Account();try {int index=-1;boolean flag2=false;for(int i=1;i<=num;i++) {HSSFRow row = sheet.getRow(i);if(String.valueOf(qqcode).equals(String.valueOf(row.getCell(0).getStringCellValue()))) {index=i;flag2=true;break;}}if(flag2)//查到了賬號名跟密碼匹配的東西 已經登陸了{ //登陸成功,讀取用戶所有信息HSSFRow row = sheet.getRow(index);acc.setQqCode(qqcode);acc.setNickName(String.valueOf(row.getCell(1).getStringCellValue()));acc.setIpAddr(String.valueOf(row.getCell(3).getStringCellValue()));acc.setPort(Integer.parseInt(String.valueOf(row.getCell(4).getStringCellValue())));acc.setAge(Integer.parseInt(String.valueOf(row.getCell(5).getStringCellValue())));acc.setSex(String.valueOf(row.getCell(6).getStringCellValue()));acc.setNation(String.valueOf(row.getCell(7).getStringCellValue()));acc.setStar(String.valueOf(row.getCell(8).getStringCellValue()));acc.setFace(String.valueOf(row.getCell(9).getStringCellValue()));acc.setRemark(String.valueOf(row.getCell(10).getStringCellValue()));acc.setSelfsign(String.valueOf(row.getCell(11).getStringCellValue()));}}catch(Exception e){e.printStackTrace();}return acc;}public boolean modifyStatus(int qqcode,int status) throws IOException{boolean bok=false;HSSFWorkbook conn=new DBConn().getWrokbook();HSSFSheet sheet=conn.getSheetAt(1);int num=sheet.getLastRowNum();if(sheet.getRow(0)==null) {return false;}try {int index=-1;boolean flag3=false;for(int i=1;i<=num;i++) {HSSFRow row = sheet.getRow(i);if(String.valueOf(qqcode).equals(String.valueOf(row.getCell(0).getStringCellValue()))){index=i;flag3=true;break;}}if(flag3) {HSSFRow row = sheet.getRow(index);String NickName=(String.valueOf(row.getCell(1).getStringCellValue()));String pwd=(String.valueOf(row.getCell(2).getStringCellValue()));String IpAddr=(String.valueOf(row.getCell(3).getStringCellValue()));String Port=(String.valueOf(row.getCell(4).getStringCellValue()));String Age=(String.valueOf(row.getCell(5).getStringCellValue()));String Sex=(String.valueOf(row.getCell(6).getStringCellValue()));String Nation=(String.valueOf(row.getCell(7).getStringCellValue()));String Star=(String.valueOf(row.getCell(8).getStringCellValue()));String Face=(String.valueOf(row.getCell(9).getStringCellValue()));String Remark=(String.valueOf(row.getCell(10).getStringCellValue()));String Selfsign=(String.valueOf(row.getCell(11).getStringCellValue()));HSSFRow currow = sheet.createRow((short)index);//在row里建立新cell(單元格),參數為列號(第一列) //設置cell的整數類型的值currow.createCell(0).setCellValue(String.valueOf(qqcode)); //設置cell浮點類型的值currow.createCell(1).setCellValue(String.valueOf(NickName)); //設置cell字符類型的值currow.createCell(2).setCellValue(String.valueOf(pwd)); //設置cell布爾類型的值currow.createCell(3).setCellValue(String.valueOf(IpAddr)); //設置cell浮點類型的值currow.createCell(4).setCellValue(String.valueOf(Port)); //設置cell字符類型的值currow.createCell(5).setCellValue(String.valueOf(Age)); //設置cell布爾類型的值currow.createCell(6).setCellValue(String.valueOf(Sex)); //設置cell浮點類型的值currow.createCell(7).setCellValue(String.valueOf(Nation)); //設置cell字符類型的值currow.createCell(8).setCellValue(String.valueOf(Star)); //設置cell布爾類型的值currow.createCell(9).setCellValue(String.valueOf(Face)); //設置cell浮點類型的值currow.createCell(10).setCellValue(String.valueOf(Remark)); //設置cell字符類型的值currow.createCell(11).setCellValue(String.valueOf(Selfsign)); //設置cell布爾類型的值currow.createCell(12).setCellValue(String.valueOf(status)); //設置cell布爾類型的值FileOutputStream fileOut = new FileOutputStream("data.xls"); conn.write(fileOut); fileOut.close();bok=true;}}catch(Exception e){e.printStackTrace();}return bok;}//返回頭像public String getFace(int qqcode) throws IOException{String face="";HSSFWorkbook conn=new DBConn().getWrokbook();HSSFSheet sheet=conn.getSheetAt(1);int num=sheet.getLastRowNum();if(sheet.getRow(num)==null) {return "face\1.jpg";} // Account acc=new Account();try {int index=-1;boolean flag4=false;for(int i=1;i<=num;i++) {HSSFRow row = sheet.getRow(i);if(String.valueOf(qqcode).equals(String.valueOf(row.getCell(0).getStringCellValue()))) {index=i;flag4=true;break;}}if(flag4) {HSSFRow row = sheet.getRow(index);face=String.valueOf(row.getCell(9).getStringCellValue());}}catch(Exception e){e.printStackTrace();}return face;}//返回所有好友,家人,同學,黑名單等資料public Vector<Account> getAllInfo(Account acc1) throws IOException{HSSFWorkbook conn=new DBConn().getWrokbook();HSSFSheet sheet=conn.getSheetAt(1);int num=sheet.getLastRowNum();if(sheet.getRow(0)==null) {return null;}Vector<Account> allInfo=new Vector<Account>();try {for (int index=0;index<=num;index++) {Account acc=new Account();//一條記錄創建一個Account對象HSSFRow row = sheet.getRow(index);acc.setQqCode(Integer.parseInt(String.valueOf(row.getCell(0).getStringCellValue())));acc.setNickName(String.valueOf(row.getCell(1).getStringCellValue()));acc.setIpAddr(String.valueOf(row.getCell(3).getStringCellValue()));acc.setPort(Integer.parseInt(String.valueOf(row.getCell(4).getStringCellValue())));acc.setAge(Integer.parseInt(String.valueOf(row.getCell(5).getStringCellValue())));acc.setSex(String.valueOf(row.getCell(6).getStringCellValue()));acc.setNation(String.valueOf(row.getCell(7).getStringCellValue()));acc.setStar(String.valueOf(row.getCell(8).getStringCellValue()));acc.setFace(String.valueOf(row.getCell(9).getStringCellValue()));acc.setRemark(String.valueOf(row.getCell(10).getStringCellValue()));acc.setSelfsign(String.valueOf(row.getCell(11).getStringCellValue()));acc.setStatus(Integer.parseInt(String.valueOf(row.getCell(12).getStringCellValue())));acc.setGroupname("myQQFriends");allInfo.add(acc);}}catch(Exception e){e.printStackTrace();}return allInfo;}//查找好友public Vector<Vector<String>> find(Account acc1) throws IOException{HSSFWorkbook conn=new DBConn().getWrokbook(); // Vector<Account> allInfo=new Vector<Account>();Vector<Vector<String>> allInfo=new Vector<Vector<String>>();HSSFSheet sheet=conn.getSheetAt(0);int num=sheet.getLastRowNum();if(sheet.getRow(0)==null) {return allInfo;}try {int index=-1;boolean flag5=false;for(int i=0;i<=num;i++) {HSSFRow row = sheet.getRow(i);if(String.valueOf(acc1.getQqCode()).equals(String.valueOf(row.getCell(0).getStringCellValue()))){index=i;flag5=true;break;}}if(flag5) {Vector<String> a=new Vector<String>(); // Account acc=new Account();//a.addElement(Integer.parseInt(String.valueOf(sheet.getCell(index,0))));HSSFRow row = sheet.getRow(index);a.addElement(String.valueOf(row.getCell(0).getStringCellValue()));a.addElement(String.valueOf(row.getCell(1).getStringCellValue()));a.addElement(String.valueOf(row.getCell(3).getStringCellValue()));a.addElement(String.valueOf(row.getCell(4).getStringCellValue()));a.addElement(String.valueOf(row.getCell(5).getStringCellValue()));a.addElement(String.valueOf(row.getCell(6).getStringCellValue()));a.addElement(String.valueOf(row.getCell(7).getStringCellValue()));a.addElement(String.valueOf(row.getCell(8).getStringCellValue()));a.addElement(String.valueOf(row.getCell(9).getStringCellValue()));a.addElement(String.valueOf(row.getCell(10).getStringCellValue()));a.addElement(String.valueOf(row.getCell(11).getStringCellValue()));a.addElement(String.valueOf(row.getCell(12).getStringCellValue()));a.addElement("myQQFriends");allInfo.add(a);}//取出朋友的信息,在線狀態,以及分組}catch(Exception e){e.printStackTrace();}return allInfo;}//添加好友public boolean addFriend(Account acc,int friendcode) throws IOException{ // System.out.println(acc.getQqCode()+" "+friendcode);boolean bok=false;HSSFWorkbook conn=new DBConn().getWrokbook();HSSFSheet sheet=conn.getSheetAt(1);int num=sheet.getLastRowNum();if(sheet.getRow(num)!=null) {num+=1;}try {//添加好友HSSFRow currow = sheet.createRow((short)num);//在row里建立新cell(單元格),參數為列號(第一列) //設置cell的整數類型的值currow.createCell(0).setCellValue(String.valueOf(acc.getQqCode())); //設置cell浮點類型的值currow.createCell(1).setCellValue(String.valueOf(acc.getNickName())); //設置cell字符類型的值currow.createCell(3).setCellValue(String.valueOf(acc.getIpAddr())); //設置cell浮點類型的值currow.createCell(4).setCellValue(String.valueOf(acc.getPort())); //設置cell字符類型的值currow.createCell(5).setCellValue(String.valueOf(acc.getAge())); //設置cell布爾類型的值currow.createCell(6).setCellValue(String.valueOf(acc.getSex())); //設置cell浮點類型的值currow.createCell(7).setCellValue(String.valueOf(acc.getNation())); //設置cell字符類型的值currow.createCell(8).setCellValue(String.valueOf(acc.getStar())); //設置cell布爾類型的值currow.createCell(9).setCellValue(String.valueOf(acc.getFace())); //設置cell浮點類型的值currow.createCell(10).setCellValue(String.valueOf(acc.getRemark())); //設置cell字符類型的值currow.createCell(11).setCellValue(String.valueOf(acc.getSelfsign())); //設置cell布爾類型的值currow.createCell(12).setCellValue(String.valueOf(acc.getStatus())); //設置cell布爾類型的值FileOutputStream fileOut = new FileOutputStream("data.xls"); conn.write(fileOut); fileOut.close();//互相添加?//狀態bok=true;}catch(Exception e){e.printStackTrace();}return bok;} //刪除好友public boolean delFriend(Account acc,int friendcode) throws IOException{HSSFWorkbook conn=new DBConn().getWrokbook();HSSFSheet sheet=conn.getSheetAt(1);FileOutputStream fileOut=null;int num=sheet.getLastRowNum();if(sheet.getRow(num)==null) {return false;}try {int index=-1;boolean flag6=false;for(int i=0;i<num;i++) {HSSFRow row = sheet.getRow(i);if(String.valueOf(friendcode).equals(String.valueOf(row.getCell(0).getStringCellValue()))) {index=i;flag6=true;break;}}if(flag6) {//逐步上移for(int i=index;i<num;i++) {HSSFRow row = sheet.getRow(i+1);String qqcode=(String.valueOf(row.getCell(0).getStringCellValue()));String NickName=(String.valueOf(row.getCell(1).getStringCellValue()));String pwd=(String.valueOf(row.getCell(2).getStringCellValue()));String IpAddr=(String.valueOf(row.getCell(3).getStringCellValue()));String Port=(String.valueOf(row.getCell(4).getStringCellValue()));String Age=(String.valueOf(row.getCell(5).getStringCellValue()));String Sex=(String.valueOf(row.getCell(6).getStringCellValue()));String Nation=(String.valueOf(row.getCell(7).getStringCellValue()));String Star=(String.valueOf(row.getCell(8).getStringCellValue()));String Face=(String.valueOf(row.getCell(9).getStringCellValue()));String Remark=(String.valueOf(row.getCell(10).getStringCellValue()));String Selfsign=(String.valueOf(row.getCell(11).getStringCellValue()));String Status=(String.valueOf(row.getCell(12).getStringCellValue()));HSSFRow currow = sheet.createRow((short)i);//在row里建立新cell(單元格),參數為列號(第一列) //設置cell的整數類型的值currow.createCell(0).setCellValue(String.valueOf(qqcode)); //設置cell浮點類型的值currow.createCell(1).setCellValue(String.valueOf(NickName)); //設置cell字符類型的值currow.createCell(2).setCellValue(String.valueOf(pwd)); //設置cell布爾類型的值currow.createCell(3).setCellValue(String.valueOf(IpAddr)); //設置cell浮點類型的值currow.createCell(4).setCellValue(String.valueOf(Port)); //設置cell字符類型的值currow.createCell(5).setCellValue(String.valueOf(Age)); //設置cell布爾類型的值currow.createCell(6).setCellValue(String.valueOf(Sex)); //設置cell浮點類型的值currow.createCell(7).setCellValue(String.valueOf(Nation)); //設置cell字符類型的值currow.createCell(8).setCellValue(String.valueOf(Star)); //設置cell布爾類型的值currow.createCell(9).setCellValue(String.valueOf(Face)); //設置cell浮點類型的值currow.createCell(10).setCellValue(String.valueOf(Remark)); //設置cell字符類型的值currow.createCell(11).setCellValue(String.valueOf(Selfsign)); //設置cell布爾類型的值currow.createCell(12).setCellValue(String.valueOf(Status)); //設置cell布爾類型的值fileOut = new FileOutputStream("data.xls"); // conn.write(fileOut); // fileOut.close();} // sheet.createRow((short)num);//最后一行置空sheet.removeRow(sheet.getRow(num));conn.write(fileOut); fileOut.close();} JOptionPane.showMessageDialog(null, "已將好友從數據庫刪除", "提示", JOptionPane.PLAIN_MESSAGE);}catch(Exception e){e.printStackTrace();}return true;} //移動好友public boolean moveFriend(Account acc,int friendcode,String groupname) throws IOException{HSSFWorkbook conn=new DBConn().getWrokbook();HSSFSheet sheet=conn.getSheetAt(1);int number=0;int num=sheet.getLastRowNum();if(sheet.getRow(num)==null) {return false;}try {int index=-1;boolean flag7=false;for(int i=0;i<=number;i++) {HSSFRow row = sheet.getRow(i);if(String.valueOf(acc.getQqCode()).equals(String.valueOf(row.getCell(0).getStringCellValue()))) {index=i;flag7=true;break;}}if(flag7) {HSSFRow row = sheet.getRow(index);String qqcode=(String.valueOf(row.getCell(0).getStringCellValue()));String NickName=(String.valueOf(row.getCell(1).getStringCellValue()));String pwd=(String.valueOf(row.getCell(2).getStringCellValue()));String IpAddr=(String.valueOf(row.getCell(3).getStringCellValue()));String Port=(String.valueOf(row.getCell(4).getStringCellValue()));String Age=(String.valueOf(row.getCell(5).getStringCellValue()));String Sex=(String.valueOf(row.getCell(6).getStringCellValue()));String Nation=(String.valueOf(row.getCell(7).getStringCellValue()));String Star=(String.valueOf(row.getCell(8).getStringCellValue()));String Face=(String.valueOf(row.getCell(9).getStringCellValue()));String Remark=(String.valueOf(row.getCell(10).getStringCellValue()));String Selfsign=(String.valueOf(row.getCell(11).getStringCellValue()));String Status=(String.valueOf(row.getCell(12).getStringCellValue()));HSSFRow currow = sheet.createRow((short)index);//在row里建立新cell(單元格),參數為列號(第一列) //設置cell的整數類型的值currow.createCell(0).setCellValue(String.valueOf(qqcode)); //設置cell浮點類型的值currow.createCell(1).setCellValue(String.valueOf(NickName)); //設置cell字符類型的值currow.createCell(2).setCellValue(String.valueOf(pwd)); //設置cell布爾類型的值currow.createCell(3).setCellValue(String.valueOf(IpAddr)); //設置cell浮點類型的值currow.createCell(4).setCellValue(String.valueOf(Port)); //設置cell字符類型的值currow.createCell(5).setCellValue(String.valueOf(Age)); //設置cell布爾類型的值currow.createCell(6).setCellValue(String.valueOf(Sex)); //設置cell浮點類型的值currow.createCell(7).setCellValue(String.valueOf(Nation)); //設置cell字符類型的值currow.createCell(8).setCellValue(String.valueOf(Star)); //設置cell布爾類型的值currow.createCell(9).setCellValue(String.valueOf(Face)); //設置cell浮點類型的值currow.createCell(10).setCellValue(String.valueOf(Remark)); //設置cell字符類型的值currow.createCell(11).setCellValue(String.valueOf(Selfsign)); //設置cell布爾類型的值currow.createCell(12).setCellValue(String.valueOf(Status)); //設置cell布爾類型的值currow.createCell(113).setCellValue("myFriends");FileOutputStream fileOut = new FileOutputStream("data.xls"); conn.write(fileOut); fileOut.close();} }catch(Exception e){e.printStackTrace();}return true;} }總結
以上是生活随笔為你收集整理的基于Java Socket的局域网聊天系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在日本申报个人所得税流程
- 下一篇: Elasticsearch安全认证