Java Swing编写udp数据传输的聊天程序demo

Java Swing编写udp数据传输的demo

事情是这个样子的,那天上软件工程课,老师和我们说,让我们一个星期内编写出一个udp进行数据传输的聊天程序,高级软件工程那本教科书上有响应的demo,但是那个代码是用VB写的,考古呢!!我就想着怎么用java来写一个,所以就有了以下内容了。
首先给大家看看作品演示

作品演示

零、如果你想用视频教学的话,我录了一个视频可以看这里【一个小时做一个UDP聊天室】

视频在此
点这里BIlibli直达l
代码在此
蓝奏云(无需注册,免积分)
曲奇云盘代码下载(需要注册,免积分)
CSDN下载(需要积分)
不知道为什么我设置的2积分,被CSDN搞到9积分
百度云盘链接
链接:https://pan.baidu.com/s/1VEtuaEfsS9ponhzkWJPr4g?pwd=1234
提取码:1234

一、项目需求

1.使用UDP
2.可视化
3.可以传输文本,语音

二、项目准备

0.下载jdk安装配置环境变量,这一步网上到处都是教材,就不拿出来写了!
1.下载eclipse 2020版(idea 在Java swing中不是很好用,所以用eclipse)

链接在此: 点此下载Eclipse 2020

2.有了这些还不够,我们还需要swing 插件

下载方法:点此查看安装方法

3.我们需要一个gson.jar包

下载方法:点此下载gson

三、新建项目

1.点击File-> New->JavaProject
2.填写项目名称,点击finish
具体情况
3.这里Module name随便写,因为我们还要删除它
在这里插入图片描述
4. 删除这个自动生成的java文件,不然系统运行不起来
删除这个
5. 右击 src->Other->找到下图的这个文件夹
Application window
6.填写包名和类名,com.ahut是安徽工业大学的意思,你们可以换自己名字,点击finish
Create Application
7.把Main中内容删除,新建一个入口函数
创建Main函数

开始写代码

首先开始明确我们的架构

两个客户端之间不直接产生关系,都是通过服务器来传递消息
架构

创建消息的Bean

1.新建一个Class ,起名叫MessageBean

public class MessageBean {
	private String name;
	private String content;
	private int type;//0正常的一个字符串,1则是语音
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public int getType() {
		return type;
	}
	public void setType(int type) {
		this.type = type;
	}
}

2.编写服务端

创建一个MyService的class ,这个就是我们的客户端
我们需要一个UDP对象-> private static DatagramSocket socket;
DatagramSocket 在java中就是UDP传输的实体类
更好的解释请看视频!!!!

代码在此
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.ArrayList;

import com.google.gson.Gson;

public class MyService extends Thread{
	public static int PORT=10005;
	private static DatagramSocket socket;
	private static ArrayList<ClientActivity> mList=new ArrayList<>();
	public MyService() {
		try {
			socket=new DatagramSocket(PORT);
		} catch (SocketException e) {
			e.printStackTrace();
		}
	}
	public static void loginGroups(ClientActivity clientActivity) {
		if(clientActivity==null)
			return;
		mList.add(clientActivity);
	}
	
	private void receiveMessage() {
		byte[] buf=new byte[1024];
		DatagramPacket datagramPacket=new DatagramPacket(buf, buf.length);
		while(true) {
			try {
				socket.receive(datagramPacket);
				String msg=new String(datagramPacket.getData(),0,datagramPacket.getLength());
				Gson gson=new Gson();
				MessageBean bean=gson.fromJson(msg, MessageBean.class);
				for(ClientActivity clientActivity:mList) {
					//发送数据给每一个客户端
					clientActivity.pushMessage(bean);
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	@Override
	public void run() {
//		while(true) {
			receiveMessage();
//		}
	}
}

3.编写客户端

这个就是我们可以看到的界面,新建ClientActivity继承JFrame
我们需要一个UDP对象-> private static DatagramSocket socket;
DatagramSocket 在java中就是UDP传输的实体类
TargetDataLine在Java中是录音的实体类

代码在此
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.DataLine.Info;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.TargetDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.awt.event.ActionEvent;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import com.google.gson.Gson;
import javax.swing.JTextArea;

public class ClientActivity extends JFrame{

	private String name;
	private JTextField textField;
	private DatagramSocket socket;
	private InetAddress ip;
	private JTextArea textArea;
	private JButton playBtn;
	
	private AudioFormat format;
	public TargetDataLine targetDataLine;
	private boolean isStartAduio=true;
	
	public ClientActivity(String name) {
		super("聊天客户端:"+name);
		this.name=name;
		setSize(500, 500);
		getContentPane().setLayout(null);
		initLayout();
		initUdp();
		show();
	}
	
	private void initLayout() {
		JButton sendBtn = new JButton("发送");
		sendBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				String msg=textField.getText();
				sendMessage(msg, 0);
			}
		});
		sendBtn.setBounds(366, 419, 97, 23);
		getContentPane().add(sendBtn);
		
		textField = new JTextField();
		textField.setBounds(10, 419, 346, 23);
		getContentPane().add(textField);
		textField.setColumns(10);
		
		JButton soundRecordBtn = new JButton("点击录音");
		soundRecordBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(isStartAduio) {
					captureAudio();
					soundRecordBtn.setText("点击结束");
				}else {
					targetDataLine.stop();
					targetDataLine.close();
					soundRecordBtn.setText("点击录音");
					sendMessage("给您发送了语言,请点击播放", 1);
					playBtn.setVisible(true);
				}
				isStartAduio=!isStartAduio;
			}
		});
		soundRecordBtn.setBounds(48, 375, 97, 23);
		getContentPane().add(soundRecordBtn);
		
		playBtn = new JButton("点击播放");
		playBtn.setVisible(false);
		playBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				playAduio();
				playBtn.setText("正在播放...");
			}
		});
		playBtn.setBounds(292, 375, 97, 23);
		getContentPane().add(playBtn);
		
		textArea = new JTextArea();
		textArea.setBounds(10, 0, 466, 365);
		getContentPane().add(textArea);
	}
	private void initUdp() {
		MyService.loginGroups(this);
		try {
			socket=new DatagramSocket();
			ip=InetAddress.getByName("127.0.0.1");
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		
	}
	public void pushMessage(MessageBean bean) {
		textArea.append(bean.getName()+":"+bean.getContent()+"\n");
		if(bean.getType()==0) {
			playBtn.setVisible(false);
		}else {
			playBtn.setVisible(true);
		}
	}
	private void sendMessage(String msg,int type) {
		MessageBean bean=new MessageBean();
		bean.setName(name);
		bean.setContent(msg);
		bean.setType(type);
		Gson gson=new Gson();
		String json=gson.toJson(bean);
		byte[] bytes=json.getBytes();
		DatagramPacket datagramPacket=new DatagramPacket(bytes, bytes.length,ip,MyService.PORT);
		try {
			socket.send(datagramPacket);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	private void captureAudio() {
		format=getAudioForamt();
		DataLine.Info dataLineInfo=new DataLine.Info(TargetDataLine.class, format);
		try {
			targetDataLine=(TargetDataLine) AudioSystem.getLine(dataLineInfo);
			new CaptureThread().start();
		} catch (LineUnavailableException e) {
			e.printStackTrace();
		}
		
	}
	private AudioFormat getAudioForamt() {
		float sampleRate=11025.0f;
		int sampleSizeInBits=16;
		int channels=1;
		boolean signed=true;
		boolean bigEndian=false;
		return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed, bigEndian);
	}
	class CaptureThread extends Thread{
		@Override
		public void run() {
			AudioFileFormat.Type fileType=AudioFileFormat.Type.WAVE;
			File audioFile=new File("chat.wav");
			try {
				targetDataLine.open(format);
				targetDataLine.start();
				AudioSystem.write(new AudioInputStream(targetDataLine), fileType, audioFile);
			} catch (LineUnavailableException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	private void playAduio()  {
		AudioInputStream as;
		try {
			as=AudioSystem.getAudioInputStream(new File("chat.wav"));
			AudioFormat format=as.getFormat();
			SourceDataLine sdl=null;
			DataLine.Info info=new DataLine.Info(SourceDataLine.class,format);
			sdl=(SourceDataLine) AudioSystem.getLine(info);
			sdl.open(format);
			sdl.start();
			int nBytesRead=0;
			byte[] abData=new byte[512];
			while(nBytesRead!=-1) {
				nBytesRead=as.read(abData,0,abData.length);
				if(nBytesRead>=0) {
					sdl.write(abData, 0, nBytesRead);
				}
			}
			sdl.drain();
			sdl.close();
			playBtn.setVisible(false);
			playBtn = new JButton("点击播放");
		} catch (UnsupportedAudioFileException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (LineUnavailableException e) {
			e.printStackTrace();
		}
	}
	
}

3.我们需要一个开启服务和打开界面的入口类Main.java

代码在此
public class Main {

	public static void main(String[] args) {
		new ClientActivity("小红");
		new ClientActivity("小明");
		MyService myService=new MyService();
		myService.start();
	}
}

  • 9
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_34165225

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值