Java聊天室之使用Socket實現(xiàn)傳遞圖片
一、題目描述
題目實現(xiàn):使用網(wǎng)絡(luò)編程時,需要通過Socket傳遞圖片。
二、解題思路
創(chuàng)建一個服務(wù)器類:ServerSocketFrame,繼承JFrame類
寫一個getserver() 方法,實例化Socket對象,啟用9527當(dāng)服務(wù)的端口。
創(chuàng)建輸入流對象,用來接收客戶端信息。
再定義一個getClientInfo()方法,用于接收客戶端發(fā)送的信息。
對文本框添加一個事件:實現(xiàn)向客戶端發(fā)磅信息。
創(chuàng)建一個客戶端類:ClientSocketFrame,繼承JFrame類。
寫一個connect() 方法,實例化Socket對象,連接本地服務(wù)的9527端口服務(wù)。
再定義一個getClientInfo()方法,用于接收服務(wù)端發(fā)送的信息。
技術(shù)重點:
通過使用DataInputStream類的read0方法,將圖片文件讀取到字節(jié)數(shù)組,然后使用 DataOutputStream類從DataOutput類繼承的write0方法輸出字節(jié)數(shù)組,從而實現(xiàn)了使用Socket傳輸圖片的功能。
三、代碼詳解
ServerSocketFrame
package com.xiaoxuzhu;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.*;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.BevelBorder;
import javax.swing.border.EtchedBorder;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
/**
* Description:
*
* @author xiaoxuzhu
* @version 1.0
*
* <pre>
* 修改記錄:
* 修改后版本 修改人 修改日期 修改內(nèi)容
* 2022/6/4.1 xiaoxuzhu 2022/6/4 Create
* </pre>
* @date 2022/6/4
*/
public class ServerSocketFrame extends JFrame {
private Image sendImg = null; // 聲明圖像對象
private Image receiveImg = null; // 聲明圖像對象
private SendImagePanel sendImagePanel = null; // 聲明圖像面板對象
private ReceiveImagePanel receiveImagePanel = null; // 聲明圖像面板對象
private File imgFile = null;// 聲明所選擇圖片的File對象
private JTextField tf_path;
private DataOutputStream out = null; // 創(chuàng)建流對象
private DataInputStream in = null; // 創(chuàng)建流對象
private ServerSocket server; // 聲明ServerSocket對象
private Socket socket; // 聲明Socket對象socket
private long lengths = -1; // 圖片文件的大小
public void getServer() {
try {
server = new ServerSocket(9527); // 實例化Socket對象
while (true) { // 如果套接字是連接狀態(tài)
socket = server.accept(); // 實例化Socket對象
out = new DataOutputStream(socket.getOutputStream());// 獲得輸出流對象
in = new DataInputStream(socket.getInputStream());// 獲得輸入流對象
getClientInfo(); // 調(diào)用getClientInfo()方法
}
} catch (Exception e) {
e.printStackTrace(); // 輸出異常信息
}
}
private void getClientInfo() {
try {
long lengths = in.readLong();// 讀取圖片文件的長度
byte[] bt = new byte[(int) lengths];// 創(chuàng)建字節(jié)數(shù)組
for (int i = 0; i < bt.length; i++) {
bt[i] = in.readByte();// 讀取字節(jié)信息并存儲到字節(jié)數(shù)組
}
receiveImg = new ImageIcon(bt).getImage();// 創(chuàng)建圖像對象
receiveImagePanel.repaint();// 重新繪制圖像
} catch (Exception e) {
} finally {
try {
if (in != null) {
in.close();// 關(guān)閉流
}
if (socket != null) {
socket.close(); // 關(guān)閉套接字
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) { // 主方法
ServerSocketFrame frame = new ServerSocketFrame(); // 創(chuàng)建本類對象
frame.setVisible(true);
frame.getServer(); // 調(diào)用方法
}
public ServerSocketFrame() {
super();
setTitle("服務(wù)器端程序");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 379, 260);
final JPanel panel = new JPanel();
getContentPane().add(panel, BorderLayout.NORTH);
final JLabel label = new JLabel();
label.setText("路徑:");
panel.add(label);
tf_path = new JTextField();
tf_path.setPreferredSize(new Dimension(140, 25));
panel.add(tf_path);
sendImagePanel = new SendImagePanel();
receiveImagePanel = new ReceiveImagePanel();
final JButton button_1 = new JButton();
button_1.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
JFileChooser fileChooser = new JFileChooser();// 創(chuàng)建文件選擇器
FileFilter filter = new FileNameExtensionFilter(
"圖像文件(JPG/GIF/BMP)", "JPG", "JPEG", "GIF", "BMP");// 創(chuàng)建過濾器
fileChooser.setFileFilter(filter);// 設(shè)置過濾器
int flag = fileChooser.showOpenDialog(null);// 顯示打開對話框
if (flag == JFileChooser.APPROVE_OPTION) {
imgFile = fileChooser.getSelectedFile(); // 獲取選中圖片的File對象
}
if (imgFile != null) {
tf_path.setText(imgFile.getAbsolutePath());// 圖片完整路徑
try {
sendImg = ImageIO.read(imgFile);// 構(gòu)造BufferedImage對象
} catch (IOException ex) {
ex.printStackTrace();
}
}
sendImagePanel.repaint();// 調(diào)用paint()方法
}
});
button_1.setText("選擇圖片");
panel.add(button_1);
final JButton button = new JButton();
button.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
try {
DataInputStream inStream = null;// 定義數(shù)據(jù)輸入流對象
if (imgFile != null) {
lengths = imgFile.length();// 獲得選擇圖片的大小
inStream = new DataInputStream(new FileInputStream(imgFile));// 創(chuàng)建輸入流對象
} else {
JOptionPane.showMessageDialog(null, "還沒有選擇圖片文件。");
return;
}
out.writeLong(lengths);// 將文件的大小寫入輸出流
byte[] bt = new byte[(int) lengths];// 創(chuàng)建字節(jié)數(shù)組
int len = -1;
while ((len = inStream.read(bt)) != -1) {// 將圖片文件讀取到字節(jié)數(shù)組
out.write(bt);// 將字節(jié)數(shù)組寫入輸出流
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
button.setText("發(fā) 送");
panel.add(button);
final JPanel panel_1 = new JPanel();
panel_1.setLayout(new BorderLayout());
getContentPane().add(panel_1, BorderLayout.CENTER);
final JPanel panel_2 = new JPanel();
panel_2.setLayout(new GridLayout(1, 0));
final FlowLayout flowLayout = new FlowLayout();
flowLayout.setAlignment(FlowLayout.LEFT);
panel_2.setLayout(flowLayout);
panel_1.add(panel_2, BorderLayout.NORTH);
final JLabel label_1 = new JLabel();
label_1.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
label_1.setText("服務(wù)器端選擇的要發(fā)送的圖片 ");
panel_2.add(label_1);
final JLabel label_2 = new JLabel();
label_2.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
label_2.setText("接收到客戶端發(fā)送的圖片 ");
panel_2.add(label_2);
final JPanel imgPanel = new JPanel();
final GridLayout gridLayout = new GridLayout(1, 0);
gridLayout.setVgap(10);
imgPanel.setLayout(gridLayout);
panel_1.add(imgPanel, BorderLayout.CENTER);
imgPanel.add(sendImagePanel);
imgPanel.add(receiveImagePanel);
sendImagePanel.setBorder(new BevelBorder(BevelBorder.LOWERED));
receiveImagePanel.setBorder(new BevelBorder(BevelBorder.LOWERED));
}
// 創(chuàng)建面板類
class SendImagePanel extends JPanel {
public void paint(Graphics g) {
if (sendImg != null) {
g.clearRect(0, 0, this.getWidth(), this.getHeight());// 清除繪圖上下文的內(nèi)容
g.drawImage(sendImg, 0, 0, this.getWidth(), this.getHeight(),
this);// 繪制指定大小的圖片
}
}
}
// 創(chuàng)建面板類
class ReceiveImagePanel extends JPanel {
public void paint(Graphics g) {
if (receiveImg != null) {
g.clearRect(0, 0, this.getWidth(), this.getHeight());// 清除繪圖上下文的內(nèi)容
g.drawImage(receiveImg, 0, 0, this.getWidth(),
this.getHeight(), this);// 繪制指定大小的圖片
}
}
}
}ClientSocketFrame
package com.xiaoxuzhu;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.Socket;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EtchedBorder;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
/**
* Description:
*
* @author xiaoxuzhu
* @version 1.0
*
* <pre>
* 修改記錄:
* 修改后版本 修改人 修改日期 修改內(nèi)容
* 2022/6/4.1 xiaoxuzhu 2022/6/4 Create
* </pre>
* @date 2022/6/4
*/
public class ClientSocketFrame extends JFrame {
private Image sendImg = null; // 聲明圖像對象
private Image receiveImg = null; // 聲明圖像對象
private SendImagePanel sendImagePanel = null; // 聲明圖像面板對象
private ReceiveImagePanel receiveImagePanel = null; // 聲明圖像面板對象
private File imgFile = null;// 聲明所選擇圖片的File對象
private JTextField tf_path;
private DataInputStream in = null; // 創(chuàng)建流對象
private DataOutputStream out = null; // 創(chuàng)建流對象
private Socket socket; // 聲明Socket對象
private Container cc; // 聲明Container對象
private long lengths = -1;// 圖片文件的大小
private void connect() { // 連接套接字方法
try { // 捕捉異常
socket = new Socket("127.0.0.1", 9527); // 實例化Socket對象
while (true) {
if (socket != null && !socket.isClosed()) {
out = new DataOutputStream(socket.getOutputStream());// 獲得輸出流對象
in = new DataInputStream(socket.getInputStream());// 獲得輸入流對象
getServerInfo();// 調(diào)用getServerInfo()方法
} else {
socket = new Socket("127.0.0.1", 9527); // 實例化Socket對象
}
}
} catch (Exception e) {
e.printStackTrace(); // 輸出異常信息
}
}
public static void main(String[] args) { // 主方法
ClientSocketFrame clien = new ClientSocketFrame(); // 創(chuàng)建本例對象
clien.setVisible(true); // 將窗體顯示
clien.connect(); // 調(diào)用連接方法
}
private void getServerInfo() {
try {
long lengths = in.readLong();// 讀取圖片文件的長度
byte[] bt = new byte[(int) lengths];// 創(chuàng)建字節(jié)數(shù)組
for (int i = 0; i < bt.length; i++) {
bt[i] = in.readByte();// 讀取字節(jié)信息并存儲到字節(jié)數(shù)組
}
receiveImg = new ImageIcon(bt).getImage();// 創(chuàng)建圖像對象
receiveImagePanel.repaint();// 重新繪制圖像
} catch (Exception e) {
} finally {
try {
if (in != null) {
in.close();// 關(guān)閉流
}
if (socket != null) {
socket.close(); // 關(guān)閉套接字
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* Create the frame
*/
public ClientSocketFrame() {
super();
setTitle("客戶端程序");
setBounds(100, 100, 373, 257);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JPanel panel = new JPanel();
getContentPane().add(panel, BorderLayout.NORTH);
final JLabel label = new JLabel();
label.setText("路徑:");
panel.add(label);
tf_path = new JTextField();
tf_path.setPreferredSize(new Dimension(140, 25));
panel.add(tf_path);
final JButton button = new JButton();
button.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
JFileChooser fileChooser = new JFileChooser();// 創(chuàng)建文件選擇器
FileFilter filter = new FileNameExtensionFilter(
"圖像文件(JPG/GIF/BMP)", "JPG", "JPEG", "GIF", "BMP");// 創(chuàng)建過濾器
fileChooser.setFileFilter(filter);// 設(shè)置過濾器
int flag = fileChooser.showOpenDialog(null);// 顯示打開對話框
if (flag == JFileChooser.APPROVE_OPTION) {
imgFile = fileChooser.getSelectedFile(); // 獲取選中圖片的File對象
}
if (imgFile != null) {
tf_path.setText(imgFile.getAbsolutePath());// 圖片完整路徑
try {
sendImg = ImageIO.read(imgFile);// 構(gòu)造BufferedImage對象
} catch (IOException ex) {
ex.printStackTrace();
}
}
sendImagePanel.repaint();// 調(diào)用paint()方法
}
});
button.setText("選擇圖片");
panel.add(button);
final JButton button_1 = new JButton();
button_1.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
try {
DataInputStream inStream = null;// 定義數(shù)據(jù)輸入流對象
if (imgFile != null) {
lengths = imgFile.length();// 獲得選擇圖片的大小
inStream = new DataInputStream(new FileInputStream(
imgFile));// 創(chuàng)建輸入流對象
} else {
JOptionPane.showMessageDialog(null, "還沒有選擇圖片文件。");
return;
}
out.writeLong(lengths);// 將文件的大小寫入輸出流
byte[] bt = new byte[(int) lengths];// 創(chuàng)建字節(jié)數(shù)組
int len = -1;
while ((len = inStream.read(bt)) != -1) {// 將圖片文件讀取到字節(jié)數(shù)組
out.write(bt);// 將字節(jié)數(shù)組寫入輸出流
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
button_1.setText("發(fā) 送");
panel.add(button_1);
final JPanel panel_1 = new JPanel();
panel_1.setLayout(new BorderLayout());
getContentPane().add(panel_1, BorderLayout.CENTER);
final JPanel panel_2 = new JPanel();
panel_2.setLayout(new GridLayout(1, 0));
panel_1.add(panel_2, BorderLayout.NORTH);
final JLabel label_1 = new JLabel();
label_1.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
label_1.setText("客戶端選擇的要發(fā)送的圖片");
panel_2.add(label_1);
final JLabel label_2 = new JLabel();
label_2.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
label_2.setText("接收到服務(wù)器端發(fā)送的圖片 ");
panel_2.add(label_2);
final JPanel imgPanel = new JPanel();
sendImagePanel = new SendImagePanel();
receiveImagePanel = new ReceiveImagePanel();
imgPanel.add(sendImagePanel);
imgPanel.add(receiveImagePanel);
final GridLayout gridLayout = new GridLayout(1, 0);
gridLayout.setVgap(6);
imgPanel.setLayout(gridLayout);
panel_1.add(imgPanel, BorderLayout.CENTER);
//
}
// 創(chuàng)建面板類
class SendImagePanel extends JPanel {
public void paint(Graphics g) {
if (sendImg != null) {
g.clearRect(0, 0, this.getWidth(), this.getHeight());// 清除繪圖上下文的內(nèi)容
g.drawImage(sendImg, 0, 0, this.getWidth(), this.getHeight(),
this);// 繪制指定大小的圖片
}
}
}
// 創(chuàng)建面板類
class ReceiveImagePanel extends JPanel {
public void paint(Graphics g) {
if (receiveImg != null) {
g.clearRect(0, 0, this.getWidth(), this.getHeight());// 清除繪圖上下文的內(nèi)容
g.drawImage(receiveImg, 0, 0, this.getWidth(),
this.getHeight(), this);// 繪制指定大小的圖片
}
}
}
}服務(wù)器啟動

客戶端啟動

以上就是Java聊天室之使用Socket實現(xiàn)傳遞圖片的詳細內(nèi)容,更多關(guān)于Java聊天室的資料請關(guān)注腳本之家其它相關(guān)文章
相關(guān)文章
java中string.trim()函數(shù)的作用實例及源碼
這篇文章主要介紹了java中string.trim()函數(shù)的作用實例及源碼,具有一定借鑒價值,需要的朋友可以參考下2018-01-01
Java中EasyPoi多sheet導(dǎo)出功能實現(xiàn)
這篇文章主要介紹了Java中EasyPoi多sheet導(dǎo)出功能實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
教你使用IDEA搭建spring源碼閱讀環(huán)境的詳細步驟
這篇文章主要介紹了使用IDEA搭建spring源碼閱讀環(huán)境的詳細步驟,本文分兩步通過實例圖文相結(jié)合給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2021-08-08
Springboot 如何指定獲取出 yml文件里面的配置值
這篇文章主要介紹了Springboot 如何指定獲取出 yml文件里面的配置值操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07
分析Java中ArrayList與LinkedList列表結(jié)構(gòu)的源碼
這篇文章主要介紹了Java中ArrayList與LinkedList列表結(jié)構(gòu)的源碼,文章最后對LinkedList和ArrayList以及Vector的特性有一個對比總結(jié),需要的朋友可以參考下2016-05-05

