1. 程式人生 > >區域網聊天室

區域網聊天室

區域網聊天室需要完成以下幾個功能:

        * 1.區域網中各主機都能參與到聊天室中聊天,即可以接發訊息,其中接受可以接受每臺主機發送的訊息,傳送的訊息每臺主機都能收到
        * 2.簡陋介面

 

 

 

實現思想:

       1.先實現介面的設計。建立自己的J711ChatRoom()類來繼承JFrame()類。即可隨意編寫介面。

       2.傳送訊息採用多播資料通道MulticastSocket,並且利用joinGroup()方法給其指定一個多播地址groupIp。每個主機都用DatagramPacket來打包自己的訊息,然後將資料包傳送到多播地址,改資料包得從指定的埠傳送,然後MulticastSocket就可以呼叫send方法把主機發送的資料包給廣播出去。

       3.接收訊息採用執行緒來實現,因為接受訊息是實時進行的,所以要實現接受的同時還能傳送訊息,則可以利用執行緒的阻塞來完成。首先在指定埠中開啟多播通道MulticastSocket,然後利用joinGroup()方法給其指定一個多播地址groupIp。然後利用receive()方法從多播通道中獲取資料包。此處獲取資料包的程式碼處於死迴圈狀態,使其保持一直接受訊息的狀態。然後將接受到的訊息append到文字域中。

      

 

 

 

一些細節:

setLayout(null);               // 設定佈局方式,為null則代表控制元件可以根據自身設定的位置任意擺放

setLocationRelativeTo(null); // 引數為null此視窗置於螢幕的中央

ms.joinGroup(“/226.81.9.8");// 地址前要加一個反斜槓 

 

 

 

 

 

以下是執行效果:





import java.awt.Color;
import java.awt.Font;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import javax.swing.border.LineBorder;

public class J711ChatRoom extends JFrame{
	
	public static void main(String[] args) {

		new J711ChatRoom();
	}

	private JLabel label1;
	private JTextArea area1;// 文字域
	private JTextArea area2;// 文字域
	private JButton button;

	private Insets margin = new Insets(10, 10, 10, 10); // 讓發出去的訊息與邊框隔開10個單位
	
	public J711ChatRoom(){
		setTitle("聊天室");
		setSize(500, 500);
		setLocationRelativeTo(null); // 引數為null此視窗置於螢幕的中央
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setResizable(false);
		
		// 設定佈局方式,為null則代表控制元件可以根據自身設定的位置任意擺放
		setLayout(null);
		initUI(); 
		setVisible(true);
		
	}
	
	private void initUI() {
		label1 = createJLabel("J711聊天室", 180, 20, 200, 30);
		area1 = createJTextArea(50, 60, 395, 230);
		area1.setMargin(margin);// 前面空兩格
			
		area2 = createJTextArea(50, 300, 395, 100);

		button = new JButton("傳送");
		button.setBounds(345, 410, 100, 30);

		new Receiver().start();
		button.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				Send(area2.getText());
				area2.setText("");
			} 
		});
		
		add(label1);
		add(area1);
		add(area2);
		add(button);
		
	}
	
	/**************傳送訊息***************/
	public void Send(String msg){
		try {
			//建立多播資料報通道 (發資料) DatagramPacket
			MulticastSocket ms = new MulticastSocket();
			//客戶端要接到訊息都必須通過下面這個地址
			InetAddress groupIp = InetAddress.getByName("226.81.9.8");
			ms.joinGroup(groupIp);//將socket通道加入多播地址
			
			
			//將需要傳送的資料打包為資料報包
			String content = msg;//廣播內容
			//資料包
			DatagramPacket dp = new DatagramPacket(content.getBytes(), content.getBytes().length);
			//先把訊息發到多播地址
			dp.setAddress(groupIp);
			dp.setPort(2426);
			
			//傳送包裹
			ms.send(dp);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/*************接收訊息**************/
	public class Receiver extends Thread{
		@Override
		public void run() {
			try {
				int count = 0;
				//佔據指定的埠開啟多播通道
				MulticastSocket ms = new MulticastSocket(2426);
				InetAddress groupIp = InetAddress.getByName("226.81.9.8");
				ms.joinGroup(groupIp);
				
				String s = "";
				Date date = null;
				SimpleDateFormat sdf;
				
				byte[] b = new byte[1024];
				//宣告資料報包,用於接收廣播資訊
				DatagramPacket dp = new DatagramPacket(b, b.length);
				while(true){
					count++;
					if (count % 8 == 0) area1.setText("");
					date = new Date();// 獲取當前時間即訊息傳送的時間
					sdf = new SimpleDateFormat("HH:mm:ss");
					
					dp = new DatagramPacket(b, b.length);
					ms.receive(dp);
					s = new String(dp.getData(), dp.getOffset(), dp.getLength());			
					s = dp.getAddress() + " "+ sdf.format(date) + "\n" + s + "\n";
					area1.append(s);
					
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	
	public JTextArea createJTextArea(int x, int y, int w, int h){
		
		JTextArea area = new JTextArea();
		area.setBounds(x, y, w, h);
		area.setLineWrap(true); // 自動換行
		area.setBorder(new LineBorder(new Color(129, 152, 48)));
		return area;
	}
	
	public JLabel createJLabel(String name, int x, int y, int w, int h){
		
		JLabel label = new JLabel(name);
		//設定控制元件的邊界         x    y   寬       高
		label.setBounds(x, y, w, h);
		label.setHorizontalTextPosition(JLabel.CENTER);	
		label.setFont(new Font("楷體", Font.BOLD, 20));
		label.setForeground(Color.RED);
		return label;
	}
}