[JAVA]程式分享--多人聊天室 此程式為SERVER端

//--------------------------------------------------------------//
// MyServer.java 2011年04月15日
//--------------------------------------------------------------//
import java.io.*;
import java.net.*;
import java.util.*;
//--------------------------------------------------------------//
//程式流程
//---MyServer  --主類別檔
//-1-main  --主程式進入點
//-2-go()   --方法  --建位連線  --等待請求連線
//     --取得連線後往下執行
//-3-Process  --內部類別 --處理程序
//-3.1-Process  --建構子 --由執行緒呼叫 --建立接收
//-3.2-run()  --方法  --執行執行緒
//-3.3-tellApiece() --方法  --告訴每人
//--------------------------------------------------------------//
//MyServer主類別檔
//--------------------------------------------------------------//
public class MyServer{
 
 Vector output;//output
 //--------------------------------------------------------------//
 //-1-主程式進入點
 //--------------------------------------------------------------//
 public static void main (String args[]){
  new MyServer().go();     
 }
 //--------------------------------------------------------------//
 //-2-建位連線
 //--------------------------------------------------------------//
 public void go() {
  //建立物件陣列
  output = new Vector();          
  try{
   //產生ServerSocket設定port:5000
   ServerSocket serverSock = new ServerSocket(8888);  
   while(true){
    //等待連線的請求--串流
    Socket cSocket = serverSock.accept();    
    //建立I/O管道
    PrintStream writer = 
     //取得Socket的輸出資料流
     new PrintStream(cSocket.getOutputStream());  
    System.out.println(writer); 
    //元件加入Vector
    output.add(writer);         
    //傳入一個Runnable物件並分派一個新的執行緒
    //建立伺服器主執行緒
    Thread t = new Thread(new Process(cSocket)); 
    //啟動執行緒
    t.start();           
    //取得連線的ip       
    System.out.println(cSocket.getLocalSocketAddress()+ 
    //執行緒的在線次數
         "有"+(t.activeCount()-1)+  
    //顯示連線人次
         "個連接");               
   } 
  }catch(Exception ex){System.out.println("連接失敗");}
 }
 //--------------------------------------------------------------//
 //-3-Process處理程序
 //--------------------------------------------------------------//
 public class Process implements Runnable{   
  //暫存資料的Buffered
  BufferedReader reader;  
  //建立一個Socket變數  
  Socket sock;            
  //----------------------------------------------------------//
  //-3.1-由執行緒呼叫---建立接收
  //----------------------------------------------------------//
  public Process(Socket cSocket)
  {
   try{
    sock = cSocket;
    //取得Socket的輸入資料流
    InputStreamReader isReader =        
    new InputStreamReader(sock.getInputStream()); 
        
    reader = new BufferedReader(isReader);
   }catch(Exception ex){
    System.out.println("連接失敗Process");
   } 
  }
  //--------------------------------------------------------------//
  //-3.2-執行執行緒
  //--------------------------------------------------------------//
  public void run(){
   String message;
   try{
       //讀取資料
    while ((message = reader.readLine())!=null){   
     System.out.println("收到"+message);
     tellApiece(message);
    }
   }catch(Exception ex){System.out.println("有一個連接離開");}
  }
  //--------------------------------------------------------------//
  //-3.3-告訴每人
  //--------------------------------------------------------------//
  public void tellApiece(String message){
   //產生iterator可以存取集合內的元素資料    
   Iterator it = output.iterator(); 
   //向下讀取元件   
   while(it.hasNext()){          
    try{
    //取集合內資料
    PrintStream writer = (PrintStream) it.next();  
    //印出
    writer.println(message); 
    //刷新該串流的緩衝。
    writer.flush();           
    }
    catch(Exception ex){
     System.out.println("連接失敗Process");
    }
   }
  }
 } 
}

此程式為CLIENT端

//--------------------------------------------------------------//
// MyClient.java 2011年04月15日
//--------------------------------------------------------------//
import java.io.*;
import java.net.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
//--------------------------------------------------------------//
//程式流程
//---MyClient   --主類別檔
//-1-main()   --主程式進入點
//-2-MyClient()   --   --設定及宣告  
//-3-EstablishConnection() --方法   --建立連線
//-4-class IncomingReader --內部類別  --接收資料
//-5-actionPerformed()  --方法   --按下之動作 
//--------------------------------------------------------------//
//MyClient主類別檔
//--------------------------------------------------------------//
public class MyClient extends JFrame implements ActionListener{  
 //宣告區
 //設定名子及ip
 String    name,ip="";       
 BufferedReader  reader;           
 PrintStream  writer;
    //建立Socket變數 
 Socket    sock;
 //顯示區域
 JTextArea   incoming = new JTextArea(15,50); 
 //輸入區域
 JTextField   outgoing = new JTextField(20);     
 JLabel    jlmane   = new JLabel("你的名字:");   
 JLabel    jlip  = new JLabel("輸入ip:");   
 JTextField   jfmane   = new JTextField("無名",10);
 JTextField   jfip   = new JTextField("127.0.0.1",10);
 JLabel    state  = new JLabel("請輸入你的名字及你的名字"); 
 
 MenuBar mBar = new MenuBar();      
 //File
 Menu mFile = new Menu("檔案");
    //Save 
 MenuItem mFileSave=new MenuItem("儲存檔案");     
 //--------------------------------------------------------------//
 //-1-主程式進入點
 //--------------------------------------------------------------//
 public static void main(String[] args){
  MyClient client = new MyClient();       //
 }
 //--------------------------------------------------------------//
 //-2-設定及宣告視窗物件
 //--------------------------------------------------------------//
 MyClient (){ 
        //設定及宣告視窗物件 
  //建立視窗JFrame
  super("多入連線Client端");          
  //用來放mane及ip--設定區域
  JPanel maneipPanel  = new JPanel();   
  //建來設定按鍵 
  JButton setmaneip = new JButton("連線設定");
  //按下設定
  setmaneip.addActionListener(this);
  //加入到JPanel
  maneipPanel.add(jlmane);
  //名字
  maneipPanel.add(jfmane);         
  maneipPanel.add(jlip);
  //位子
  maneipPanel.add(jfip); 
  //設定
  maneipPanel.add(setmaneip); 
        //排版BorderLayout設定區域在上方----  
  getContentPane().add(BorderLayout.NORTH,maneipPanel);  
  //JButton("送出")
  JButton sendButton = new JButton("送出");
  //按下
  sendButton.addActionListener(this);       
  //對話區域-----
  //設置為 true,則當行的長度大於所分派的寬度時,將換行
  incoming.setLineWrap(true);         
  //設置為 true,則當行的長度大於所分派的寬度時,將在單詞邊界(空白)處換行
  incoming.setWrapStyleWord(true); 
  //不可編輯的  
  incoming.setEditable(false); 
  //JScrollPane  
  JScrollPane qScroller = new JScrollPane(incoming);
  //垂直滾動  
  qScroller.setVerticalScrollBarPolicy(
    ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); 
  //水平滾動
  qScroller.setHorizontalScrollBarPolicy(
    ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
  JPanel mainPanel = new JPanel();       
  mainPanel.add(qScroller);
  mainPanel.add(outgoing);
  mainPanel.add(sendButton);
  //對話區域在中間------
  getContentPane().add(BorderLayout.CENTER,mainPanel);  
  
  //Menu事件
  mFileSave.addActionListener(this); 
  //加入MenuItem  
  mFile.add(mFileSave);  
  //加入Menu
  mBar.add(mFile);
  //MenuBar
  setMenuBar(mBar);
  //狀態區域在下方----
  getContentPane().add(BorderLayout.SOUTH,state);    
  setSize(600,450);
  setVisible(true);
  //離開 
  addWindowListener(new WindowAdapter()      
  {
   public void windowClosing(WindowEvent e){
    System.out.println("離開聊天室");
    System.exit(0);
   }
  });
 }
 
 //--------------------------------------------------------------//
 //-3-建立連線
 //--------------------------------------------------------------//
 private void EstablishConnection(){
  try{
   //請求建立連線
   sock = new Socket(ip,8888);      
   //建立I/O資料流
   InputStreamReader streamReader =  
     //取得Socket的輸入資料流
      new InputStreamReader(sock.getInputStream());  
   //放入暫存區
   reader = new BufferedReader(streamReader);    
   //取得Socket的輸出資料流
   
   writer = new PrintStream(sock.getOutputStream());
   //連線成功
   state.setText("網路建立-連線成功"); 
   System.out.println("網路建立-連線成功");    
   
  }catch(IOException ex ){
   System.out.println("建立連線失敗");
  }
 }
 //--------------------------------------------------------------//
 //-4-接收資料
 //--------------------------------------------------------------//
 public class IncomingReader implements Runnable{
  public void run(){
   String message;
   try{
    while ((message = reader.readLine()) != null){
    incoming.append(message+'\n');
    }
   }catch(Exception ex ){ex.printStackTrace();}
  }
 } 
 //--------------------------------------------------------------//
 //-5-按下之動作
 //--------------------------------------------------------------//
 public void actionPerformed(ActionEvent e){
  String str=e.getActionCommand();   
  //按下設定
  if(str.equals("連線設定")){
   //設定名字
   name = jfmane.getText();
   //設定ip,此程式目前無作用
   ip  = jfip.getText(); 
   //狀態
   state.setText("設定"+name+":"+ip); 
   //建立連線----
   EstablishConnection();          
   //建立接收資料執行緒----
   Thread readerThread = new Thread(new IncomingReader());  
   readerThread.start();
  //按下送出   
  }else if(str.equals("送出")){    
   //不可沒有ip及送出空白
   if((ip!=null)&&(outgoing.getText()!=""))    
   {
    try{//送出資料
        writer.println((name+":"+outgoing.getText())); 
     //刷新該串流的緩衝。
     writer.flush();         
    }catch(Exception ex ){
     System.out.println("送出資料失敗");
    }
    //清完輸入欄位
    outgoing.setText("");        
   }
  }else if (str.equals("儲存檔案"))       
  {               
   try{             
    FileWriter f=          
      new FileWriter("log.txt");     
    f.write(incoming.getText());      
    f.close();           
    state.setText("儲存檔案成功");
   }catch (IOException e2){
    state.setText("儲存檔案失敗");
   }              
  } 
 }
}

 

 

其它文章

文章標籤
全站熱搜
創作者介紹
創作者 PG Levin Li 的頭像
PG Levin Li

程式開發學習之路

PG Levin Li 發表在 痞客邦 留言(0) 人氣(2,868)