1. 說明
此項目使用到的Java基礎知識:
- Java網絡通信
- Java多線程
- Java輸入輸出流
- Java AWT 圖形用戶界面繪製
每個知識點參考教程:
- Java基礎_18 | Java中網絡通信程序的設計(url爬蟲,TCP/UDP socket程序,socket文件傳輸程序)
- Java基礎_17 | Java多線程程序設計(Java中兩種創建線程的方法、多線程之間的同步和互斥)
- Java基礎_16 | Java中的輸入輸出系統(字節流、字符流)
- Java基礎_15 | Java中的圖形用戶界面包AWT使用詳解
如果有興趣,還可以添加網絡文件傳輸功能,參考教程:
2. 服務端源碼
//服務器端
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
public class Server {
public static void main(String[] args) {
ServeMainFrame serveMainFrame = new ServeMainFrame("服務器"); //創建主窗體,標題爲“服務器”
serveMainFrame.setVisible(true); //設置主窗體可視化
}
}
/*主窗體類*/
class ServeMainFrame extends Frame{
private final int DEFAULT_WDITH = 500, //窗體默認寬度
DEFAULT_HEIGHT = 400; //窗體默認高度
private Font font = new Font("name",Font.PLAIN,18);
private TextField portInput = new TextField("8000",5), //端口號輸入文本框(默認8000)
userInput = new TextField("",46); //用戶輸入文本框
private TextArea receieveInput = new TextArea("Welcome to Server!",12,42); //聊天記錄顯示文本域
private Panel setPanel = new Panel(), //設置界面(容器)(容器默認FlowLayout)
receievePanel = new Panel(), //接收界面(容器)
sendPanel = new Panel(); //發送界面(容器)
private StartButton startButton = new StartButton("Start");
private ServerSocket ss = null; //創建服務器套接字(必須要初始化null)
private Socket s = null; //用於接收處理客戶端請求返回的套接字
DataInputStream dis = null;
private DataOutputStream dos = null;
private ServerSendButton serverSendButton = new ServerSendButton("send");
private ReceieveClient receieveClient =null;
public ServeMainFrame(String title) {
super(title); //調用父類構造方法,生成帶標題的窗體
addWindowListener(new WindowsClosed()); //添加窗體監聽器,用於關閉窗口
setBounds(80, 80, DEFAULT_WDITH, DEFAULT_HEIGHT); //設置窗體位置和大小
setResizable(false); //設置用戶不可調整大小
add(setPanel,"North");//添加端口號設置容器到窗體
setPanel.add(new Label("Port"));
setPanel.add(portInput);
setPanel.add(startButton);
add(receievePanel, "Center"); //添加聊天記錄顯示容器到窗體
receieveInput.setFont(font);
receievePanel.add(receieveInput, "Center");
add(sendPanel, "South"); //添加用戶發送容器到窗體
sendPanel.add(new Label("say: "));
sendPanel.add(userInput);
sendPanel.add(serverSendButton);
}
/*啓動按鈕(實現監聽器接口)*/
class StartButton extends Button implements ActionListener{
public StartButton(String name) {
super(name);
addActionListener(this); //自身已經實現監聽器接口,很重要的代碼!!!
}
public void actionPerformed(ActionEvent e) {
try {
setEnabled(false);
ss = new ServerSocket(Integer.valueOf(portInput.getText())); //利用portInput中的端口號轉化爲整數,創建一個ServerSocket
receieveInput.append("\nserver starting......"); //顯示server starting......
s = ss.accept(); //等待客戶端的連接請求
receieveInput.append("\nclient contect successfully"); //連接成功後顯示client contect successfully
//創建從客戶端的輸入流
dos = new DataOutputStream(s.getOutputStream());
dis =new DataInputStream(s.getInputStream());
receieveClient = new ReceieveClient(); //創建一個線程,讀取客戶端輸入
receieveClient.start();; //啓動該線程
}
catch(IOException ioe) {
receieveInput.append('\n'+ioe.toString());
}
finally {
}
}
}
/*創建一個線程,讀取客戶端輸入*/ //如果實現Runable接口,則會進入死循環
class ReceieveClient extends Thread{
public void run() {
try {
String str = dis.readUTF();
while(str != null) {
receieveInput.append('\n'+"client say: "+ str);
str = dis.readUTF();
}
}
catch(IOException ioe) {
receieveInput.append('\n'+ioe.toString());
}
}
}
/*服務器發送按鈕*/
class ServerSendButton extends Button implements ActionListener{
public ServerSendButton(String name) {
super(name);
addActionListener(this); //自身已經實現監聽器接口,很重要的代碼!!!
}
public void actionPerformed(ActionEvent e) {
try {
dos.writeUTF(userInput.getText());
dos.flush();
receieveInput.append('\n'+"say to client: "+userInput.getText());
userInput.setText("");
}
catch(IOException ioe) {
receieveInput.append('\n'+ioe.toString());
}
}
}
/*繼承自Windows監聽器,重寫關閉窗體的方法*/
class WindowsClosed extends WindowAdapter{
public void windowClosing(WindowEvent e) {
System.exit(-1); //程序終止
}
}
}
運行起來效果如下:
3.客戶端源碼
//客戶端
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
public class Client {
public static void main(String[] args) {
ClientMainFrame clientMainFrame = new ClientMainFrame("客戶端"); //創建主窗體,標題爲“服務器”
clientMainFrame.setVisible(true); //設置主窗體可視化
}
}
/*主窗體類*/
class ClientMainFrame extends Frame {
private final int DEFAULT_WDITH = 500, //窗體默認寬度
DEFAULT_HEIGHT = 400; //窗體默認高度
private Font font = new Font("name",Font.PLAIN,18);
private TextField ipInput = new TextField("127.0.0.1",8), //ip地址輸入文本框(默認127.0.0.1)
portInput = new TextField("8000",5), //端口號輸入文本框(默認8000)
userInput = new TextField("",46); //用戶輸入文本框
private TextArea receieveInput = new TextArea("Welcome to Client!",12,42); //聊天記錄顯示文本域
private Panel setPanel = new Panel(), //設置界面(容器)(容器默認FlowLayout)
receievePanel = new Panel(), //接收界面(容器)
sendPanel = new Panel(); //發送界面(容器)
private ConnectButton connectButton = new ConnectButton("Connect");
private ClientSendButton clienttSendButton = new ClientSendButton("send");
private Socket s = null; //用於接收處理客戶端請求返回的套接字
private DataOutputStream dos = null; //客戶端輸出流
private DataInputStream dis = null;
ReceieveServer receieveServer = null;
public ClientMainFrame(String title) {
super(title); //調用父類構造方法,生成帶標題的窗體
addWindowListener(new WindowsClosed()); //添加窗體監聽器,用於關閉窗口
setBounds(600, 80, DEFAULT_WDITH, DEFAULT_HEIGHT); //設置窗體位置和大小
setResizable(false); //設置用戶不可調整大小
add(setPanel,"North"); //添加設置容器到窗體
setPanel.add(new Label("Server IP: "));
setPanel.add(ipInput);
setPanel.add(new Label("Port: "));
setPanel.add(portInput);
setPanel.add(connectButton);
add(receievePanel, "Center"); //添加聊天記錄顯示容器到窗體
receieveInput.setFont(font);
receievePanel.add(receieveInput, "Center");
add(sendPanel, "South"); //添加用戶發送容器到窗體
sendPanel.add(new Label("say: "));
sendPanel.add(userInput);
sendPanel.add(clienttSendButton);
}
/*連接按鈕(實現監聽器接口)*/
class ConnectButton extends Button implements ActionListener{
public ConnectButton(String name) {
super(name);
addActionListener(this); //自身已經實現監聽器接口,很重要的代碼!!!
}
public void actionPerformed(ActionEvent e) {
try {
setEnabled(false);
s = new Socket(ipInput.getText(),Integer.valueOf(portInput.getText())); //等待客戶端的連接請求
receieveInput.append("\nserver contect successfully!"); //連接成功後顯示client contect successfully
dos = new DataOutputStream(s.getOutputStream());
dis = new DataInputStream(s.getInputStream());
receieveServer = new ReceieveServer();
receieveServer.start();
}
catch(IOException ioe) {
receieveInput.append('\n'+ioe.toString());
}
finally {
}
}
}
/*客戶端發送按鈕*/
class ClientSendButton extends Button implements ActionListener{
public ClientSendButton(String name) {
super(name);
addActionListener(this); //自身已經實現監聽器接口,很重要的代碼!!!
}
public void actionPerformed(ActionEvent e) {
try {
dos.writeUTF(userInput.getText());
dos.flush();
receieveInput.append('\n'+"say to serve: "+userInput.getText());
userInput.setText("");
}
catch(IOException ioe) {
receieveInput.append('\n'+ioe.toString());
}
}
}
/*創建一個線程,讀取服務器輸入*/
class ReceieveServer extends Thread{
public void run() {
try {
String str = dis.readUTF();
while(str != null){
receieveInput.append('\n'+"serve say: "+str);
str = dis.readUTF();
}
}
catch(IOException ioe) {
receieveInput.append('\n'+ioe.toString());
}
}
}
/*繼承自Windows監聽器,重寫關閉窗體的方法*/
class WindowsClosed extends WindowAdapter{
public void windowClosing(WindowEvent e) {
System.exit(-1); //程序終止
}
}
}
運行起來效果如下:
4. 運行效果
啓動服務器監聽
客戶端連接服務器
客戶端連接之後在服務端也可以看到:
客戶端發送消息
服務端發送消息
接收更多精彩文章及資源推送,歡迎訂閱我的微信公衆號:『mculover666』。