Java基于TCP协议的网络语音聊天
本聊天是基于tcp协议进行的,其本质为:本地录音->将录音通过网络编程转发给他人->他人进行录音的播放。
所需知识:多线程,基于tcp协议的网络编程
进行语音播放与录制,需要jar包:https://pan.baidu.com/s/1tljFVTZ4O8LQjs2ZOG1-xQ 提取码:95sm
首先导入jar包,导入jar包的方法可以参考链接:https://blog.csdn.net/qq_52015408/article/details/122012862
如果需要进行多人的语音聊天室,则需要一个服务器,进行语音的转发。
在开启聊天时,只需开启一个Sever(服务器),该类会自己调用SeverThread类。然后开启多个客户端,便可以进行语音聊天了。
服务器(Sever)
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
public class Sever implements Runnable{
ArrayList<Socket> sockets = new ArrayList<>();
int port;
ServerSocket socket;
public Sever(int port) {
this.port = port;
try {
System.out.println("服务器ip"+InetAddress.getLocalHost()+"\n服务器端口号"+port);
try {
socket = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
public void run(){
while (true){
try {
Socket accept = socket.accept();
synchronized (accept){
sockets.add(accept);}
new Thread(new SeverThread(accept,sockets)).start();
} catch (IOException e) {
}
}
}
public static void main(String[] args) {
new Thread(new Sever(8888)).start();
}
}
服务器(SeverThread)
import java.io.*;
import java.net.Socket;
import java.util.ArrayList;
public class SeverThread extends Sever implements Runnable{
Socket socket;
ArrayList<Socket> sockets = new ArrayList<>();
String name;
public SeverThread(Socket socket,ArrayList<Socket> sockets) {
this.socket = socket;
this.sockets = sockets;
}
public void run(){
while (true)
accepmessage();
}
public void accepmessage() {
try {
InputStream reader = socket.getInputStream();
byte[] bytes = new byte[1024];
while (reader.read(bytes)!= -1) {
sendmessage(bytes);
bytes = new byte[1024];
}
} catch (Exception e) {
try {
socket.close();
} catch (IOException ioException) {
}
sockets.remove(socket);
}
}
public void sendmessage(byte[] message){
OutputStream write1 = null;
for (Socket socket1 : sockets) {
try {
if (socket1.equals(this.socket))
continue;//如果是当前用户发出的声音,则跳过,否则会产生回音
write1 = socket1.getOutputStream();
write1.write(message);
} catch (IOException e) {
}
}
}
}
客户端
import javax.sound.sampled.*;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
public class Oatmeala implements Runnable{
AudioFormat format = new AudioFormat( 8000f, 16, 1, true, false);
TargetDataLine targetDataLine;
SourceDataLine sourceDataLine;
OutputStream write;
InputStream read;
public Oatmeala(OutputStream write, InputStream read) {
this.write = write;
this.read = read;
try{
targetDataLine = AudioSystem.getTargetDataLine(format);
targetDataLine.open(format);
targetDataLine.start();
sourceDataLine = AudioSystem.getSourceDataLine(format);
sourceDataLine.open(format);
sourceDataLine.start();}catch (Exception e){
}
int len;
byte[] bytes = new byte[1024];
try{
while ((len = read.read(bytes))!=-1) {
sourceDataLine.write(bytes, 0,len);//播放声音
bytes = new byte[1024];
}
}catch (Exception e){
}
}
byte[] b = new byte[1024];
public void run(){
try {
while(true) {
targetDataLine.read(b, 0, b.length);//录制声音
write.write(b);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception{
Socket socket = new Socket(InetAddress.getLocalHost(), 8888);
OutputStream write = socket.getOutputStream();
InputStream read = socket.getInputStream();
new Oatmeala(write,read);
}
}