[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("儲存檔案失敗");
}
}
}
}

 

 



















其它文章

arrow
arrow
    創作者介紹
    創作者 PG Levin Li 的頭像
    PG Levin Li

    程式開發學習之路

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