簡介
Java是一個強大的面向對象開發語言,支持很多功能,比如,通過Socket編程達到的C/S通訊,基於Windows的編程,基於CONSOLE的編程,還有數據庫連接,圖象和聲音編程等。 Java多用在基於INTERNET的網絡編程上,創建一些嵌入到HTML頁面中的Applet小程序來實現。
在開始實際編寫代碼之前,為了使得概念更加清晰,需要提及幾個重要的概念。廣播信使(broadcast messenger)是要創建一個服務器,用來負責接收和響應來自客戶機的網絡消息。這個就叫做廣播(Broadcasting),意思是發送數據包或者消息到所有的客戶機。
這裡使用的是服務器/客戶機(C/S)框架,因為有一台計算機扮演服務器的角色來響應客戶機的消息,所有其他的計算機都扮演客戶機的角色,僅僅只是發送請求到服務器來執行它們的一些任務。Socket是連接計算機彼此的一個邏輯連接。要創建一個socket,需要提供一個端口號和一個主機IP地址/主機名。
多線程意味著一個進程的多個線程能夠同時運行在分配給它們的同一個處理器上,就感覺好象只有進程在運行。所以,通過多線程技術,許多客戶機可以連接服務器的同一個端口。線程是占有資源的進程或程序的一部分,比如文件,I/O等等,它們能夠獨立運行。
Java代碼解釋
首先,我們創建一個服務器,創建一個server和client類,並import下面幾個文件:
import java.io.*;
import java.net.*;
import java.awt.*;
為server類設計一個interface使得從客戶機到達的請求能夠顯示在一個window form裡。一個簡單server window設計如下:
Figure 1: 一個服務器窗口,顯示所有輸入和輸出,客戶機名和IP地址的日志。
我們在窗口頂部創建了一個菜單,在中間創建了一個TextArea和一個Help對話框。我們設置窗口的容器布局管理器為流布局(FlowLayout)。這個流布局管理器以行來放置組件,當一行滿後,自動將組件換到下一行。在JAVA中也有其他的布局管理器可用,比如Border layout manager, Grid layout manager, Card layout manager, Box layout manager, 和GridBag layout manager。下面給出代碼:
public class ChatServer extends JFrame {
public ChatServer(String title) //CONSTRUCTOR TO INITIALIZE THE
//ChatServer CLASS
{
output = new TextArea (15,40); //output IS A TextArea COMPONENT
//OF THE ChatServer CLASS
output.setEditable (false);
output.setFont(f);
output.setForeground(Color.blue);
setTitle(title); //TO SET THE TITLE OF THE CLIENT WINDOW
setJMenuBar(menuBar); //TO INITIALIZE THE MENU BAR ON THE WINDOW
JMenu fileMenu = new JMenu("File");
JMenu colorMenu = new JMenu("Color");
JMenu helpMenu = new JMenu("Help");
//Main menu Shortcuts:
fileMenu.setMnemonic('F');
colorMenu.setMnemonic('C');
helpMenu.setMnemonic('H');
//About Dialog init:
aboutItem = new JMenuItem("About");
//aboutItem.addActionListener((ActionListener)this);
helpMenu.add(aboutItem);
addMenuItem(helpMenu,aboutAction = new AboutAction("About"));
//Initialize menu items:
menuBar.add(fileMenu);
menuBar.add(colorMenu);
menuBar.add(helpMenu);
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
class AboutAction extends AbstractAction //CREATES AN ABSTRACT
//INTERNAL CLASS FOR
//About
{
JOptionPane opt;
String name;
public AboutAction(String Name)
{
this.name=Name;
}
//About menu event:
public void actionPerformed(ActionEvent ae)
{
//if(ae.getSource() == aboutAction)
{
JOptionPane.showMessageDialog(opt,"ChitChat_Broadcast_Messenger\nCopyright
Fatima_Ahmed","About_ChitChat_Broadcast_Messenger",J
OptionPane.INFORMATION_MESSAGE);
}
}
}
Figure 2: ABOUT對話框
public static void main (String args[]) throws IOException {
ChatServer ServerWindow = new ChatServer("ChitChat Broadcast
Messenger: Server Window");
//CREATES AN OBJECT OF SERVER
Toolkit theKit = ServerWindow.getToolkit(); //TO CREATE AN OBJECT
//OF ToolKit
Dimension wndSize = theKit.getScreenSize();
ServerWindow.setBounds(wndSize.width/4,wndSize.height/4,wndSize.width/2,wndSize.height/2);
ServerWindow.setVisible(true);
ServerWindow.getContentPane().add ("North", output);
//TO ADD THE TextArea (output) AT THE NORTH OF THE WINDOW
ServerWindow.getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER));
//TO SET THE LAYOUT AS CENTRALLY FLOW
ServerWindow.pack(); //TO PACK THE SERVER WINDOW WITH ABOVE
//INITIALIZE COMPONENTS
if (args.length != 1)
throw new IllegalArgumentException ("Syntax: ChatServer<port>");
int port = Integer.parseInt (args[0]);
String logins;
ServerSocket server = new ServerSocket (port);
//TO CREATE AN OBJECT FOR SERVER'S SOCKET
while (true) {
Socket client = server.accept (); //CALLS THE accept()
//METHOD WHENEVER THE
//CLIENTS REQUEST
System.out.println ("Accepted from " + client.getInetAddress ()+ " with name "+logins);
ChatHandler handler = new ChatHandler (client,yourname);
handler.start (); //THE BROADCASTING OF MESSAGES IS
//STARTED BY start() METHOD
output.append ("\n Accepted from " + client.getInetAddress ()+"\n");
}
}
socket是通過另一個類“ChatHandler”創建的,是包含在Demo Project文件中。現在,我們設計一個Client類:
Figure 3: Client信使窗口詢問每次連接初始化的用戶登陸名
Figure 4: 一個客戶機窗口,包含一些字體,顏色選取框和一個菜單來控制窗口。
在Client類中導入以下文件。我們已經創建了另一個類“SketchFrame”,它是用來定義一些客戶機窗口的interface的。我們描敘一下JAVA中的Socket類的一些基本功能,並在客戶端線程上實現了start ( ), run ( ),和stop ( )方法。這個類有以下導入的文件:
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class ChatClient implements Runnable, WindowListener,
ActionListener, ListSelectionListener {
protected String host;
protected int port;
public TextArea output;
protected TextField input;
String yourname;
SketchFrame window;
public ChatClient (String host, int port, SketchFrame window) {
//CONSTRUCTOR INITIALIZING THE ChatClient CLASS
this.host = host; //host AND port WILL BE USED TO OPEN THE
//SOCKET
this.port = port;
this.yourname=JOptionPane.showInputDialog("Enter Login name:");
//TO CREATE AN INPUT DIALOG BOX
window.setSize(100,100); //TO SET THE SIZE OF THE CLIENT
//WINDOW
window.getContentPane().add (output,BorderLayout.CENTER);
//TO ADD TextArea (output) AT THE CENTER OF THE WINDOW
window.getContentPane().add (input,BorderLayout.SOUTH);
//TO ADD THE Textbox (input) AT THE BOTTOM (SOUTH)
protected DataInputStream dataIn;
protected DataOutputStream dataOut;
protected Thread listener;
public synchronized void start () throws IOException {
//THREAD SYNCHRONIZATION METHOD FOR STARTING BROADCAST
if (listener == null) {
Socket socket = new Socket (host, port); //TO INITIALIZE
//THE SOCKET
try {
dataIn = new DataInputStream(new BufferedInputStream (socket.getInputStream ()));
dataOut = new DataOutputStream(new BufferedOutputStream (socket.getOutputStream ()));
dataOut.writeUTF (yourname+" has loggged on\n");
}
catch (IOException ex)
{
socket.close ();
throw ex;
}
}
listener = new Thread (this);
listener.start ();
window.setVisible (true);
}
}
public synchronized void stop () throws IOException
//THREAD SYNCHRONIZATION METHOD FOR STOPPING THE BROADCAST
{
if (listener != null)
{
listener.interrupt ();
listener = null;
dataOut.close ();
}
public void run() { //THREAD METHOD FOR READING A NEW MESSAGE
//LINE FROM THE CLIENT
try {
while (!Thread.interrupted ())
{
String line = dataIn.readUTF ();
output.append (line + "\n");
}
}
catch (IOException ex)
{
handleIOException (ex);
}
}
當用戶運行程序並在輸入框中輸入一些信息,然後回車後,start ( )方法就被調用,並創建了一個socket來初始化輸入流和輸出流,發送在客戶端輸入的消息給服務器,服務器再廣播這個消息到其他客戶端。只要對話建立,那麼run ( )將被調用,並發送消息。當用戶退出程序時,stop ( )方法被調用,並關閉socket連接。