簡單對話聊天窗口實現
實現一個簡單的同網段雙端通信。要用到ServerSocket類以及Socket類。
ServerSocket
這個類實現了服務器套接字。 服務器套接字等待通過網絡進入的請求。 它根據該請求執行一些操作,然後可能將結果返回給請求者。服務器套接字的實際工作由SocketImpl類的實例執行。 應用程序可以更改創建套接字實現的套接字工廠,以配置自己創建適合本地防火牆的套接字。
- accept():偵聽要連接到此套接字並接受它。這裏會得到一個Socket對象,使用Socket對象可以分別獲取到輸入流以及輸出流
Socket
該類實現客戶端套接字(也稱爲“套接字”)。 套接字是兩臺機器之間通訊的端點。套接字的實際工作由SocketImpl類的實例執行。 應用程序通過更改創建套接字實現的套接字工廠,可以配置自己創建適合本地防火牆的套接字。
實現思路
使用Frame模擬對話窗口,一端爲服務器端,一端爲客戶端,實現兩端通信。
1. 建立窗口
2. 兩端建立連接,實現數據發送
3. 建立線程實現數據接收
建立窗口
需要建立一個帶有文本域(顯示對話記錄),一個文本框(輸入信息),一個按鈕(發送功能)。要爲按鈕添加事件監聽,當單擊發送時將數據發送到服務器端並清空輸入文本框。
建立連接
使用ServerSocket與Socket建立兩端連接,服務器端使用ServerSocket,客戶端使用Socket,綁定端口指定IP
數據接收
在窗體建立之時就開始不停的進行數據的接收(使用線程)
具體實現
服務器端
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* 服務器端
*
* @author xer
*
*/
public class Server extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
TextArea talkArea;
JPanel bottomPanel;
TextField input;
JButton send;
String title;
String time;
String text;
String msg;
ServerSocket serverSocket;
Socket accept;
DataInputStream dis; //接收數據
DataOutputStream dos; //發送數據
public Server() {
//創建窗體
init();
//建立連接
connect();
//啓動 線程讀取數據
new ServerThread(this).start();
}
/**
* 建立連接
*/
private void connect() {
try {
serverSocket = new ServerSocket(9999);
accept = serverSocket.accept();
// new ConnectThread(this).start();
//接收數據
InputStream inputStream = accept.getInputStream();
dis = new DataInputStream(inputStream);
//發送數據
OutputStream outputStream = accept.getOutputStream();
dos = new DataOutputStream(outputStream);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 創建窗體
*/
private void init() {
this.setTitle("服務器端");
this.setVisible(true);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(3);
this.setSize(500, 600);
//添加聊天界面
talkArea = new TextArea();
//Panel
bottomPanel = new JPanel();
// bottomPanel.setPreferredSize(new Dimension(500, 150));
//輸入框
input = new TextField();
input.setPreferredSize(new Dimension(400, 30));
//發送按鈕
send = new JButton("發送");
send.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//獲取窗體標題 獲取時間 獲取內容
title = Server.this.getTitle();
time = new SimpleDateFormat("HH:mm:ss").format(new Date());
text = input.getText();
msg = " "+title+" "+time+"\r\n\t"+text+"\r\n";
talkArea.append(msg);
input.setText("");
try {
dos.writeUTF(msg);
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
bottomPanel.add(input);
bottomPanel.add(send, BorderLayout.EAST);
this.add(talkArea,BorderLayout.CENTER);
this.add(bottomPanel,BorderLayout.SOUTH);
}
}
客戶端
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* 客戶端
*
* @author xer
*
*/
public class Client extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
TextArea talkArea;
JPanel bottomPanel;
TextField input;
JButton send;
String title;
String time;
String text;
String msg;
Socket socket;
DataInputStream dis;
DataOutputStream dos;
public Client(String name) {
//創建窗體
init(name);
//建立連接
connect();
//啓動 線程讀取數據
new ClientTherad(this).start();
}
private void connect() {
try {
socket = new Socket(InetAddress.getLocalHost(), 9999);
//接收數據
InputStream inputStream = socket.getInputStream();
//發送數據
OutputStream outputStream = socket.getOutputStream();
dis = new DataInputStream(inputStream);
dos = new DataOutputStream(outputStream);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 創建窗體
*/
private void init(String name) {
this.setTitle(name);
this.setVisible(true);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(3);
this.setSize(500, 600);
//添加聊天界面
talkArea = new TextArea();
//Panel
bottomPanel = new JPanel();
// bottomPanel.setPreferredSize(new Dimension(500, 150));
//輸入框
input = new TextField();
input.setPreferredSize(new Dimension(400, 30));
//發送按鈕
send = new JButton("發送");
send.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//獲取窗體標題 獲取時間 獲取內容
title = Client.this.getTitle();
time = new SimpleDateFormat("HH:mm:ss").format(new Date());
text = input.getText();
msg = " "+title+" "+time+"\r\n\t"+text+"\r\n";
talkArea.append(msg);
input.setText("");
try {
dos.writeUTF(msg);
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
bottomPanel.add(input);
bottomPanel.add(send, BorderLayout.EAST);
this.add(talkArea,BorderLayout.CENTER);
this.add(bottomPanel,BorderLayout.SOUTH);
}
}
客戶端接收數據線程
import java.io.IOException;
public class ClientTherad extends Thread {
Client client;
public ClientTherad(Client client) {
this.client = client;
}
@Override
public void run() {
try {
while(true) {
String msg = client.dis.readUTF();
client.talkArea.append(msg);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
服務器端接收數據線程
import java.io.IOException;
public class ServerThread extends Thread{
Server server;
public ServerThread(Server server) {
this.server = server;
}
@Override
public void run() {
try {
while(true) {
String msg = server.dis.readUTF();
// server.dos.writeUTF(msg);
server.talkArea.append(msg);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
客戶端啓動線程
public class ClientThreadStart extends Thread {
static int i = 0;
@Override
public void run() {
synchronized (this) {
new Client(++i+"");
}
}
}
服務器端啓動線程
public class StartThread extends Thread {
@Override
public void run() {
new Server();
}
}
啓動測試類
public class Start {
public static void main(String[] args) {
new StartThread().start();
new ClientThreadStart().start();
new ClientThreadStart().start();
}
}
當然這裏創建多個客戶端是想實現多個用戶同時在服務器端通信,達到討論組效果,結果爲成功,還在尋找方法,後續更新吧