1.语音采集:客户端程序,调用音频驱动,实时采集”麦克风(mic)”的语音数据,保存到内存中。
2. 语音传输:将内存中语音数据,通过TCP/IP协议传输到服务器端。
3. 语音播放:服务器接收音频数据,并实时播放。
4. 设计可操作图形界面

5. 作为可选的扩充功能1,实现端与端之间的双向通信。

ps:服务端界面显示了本地的IP地址。

客户端和服务的都有保存音频文件输入框

 

1。服务端代码:
import java.awt.BorderLayout;
 import java.awt.Font;
 import java.awt.GridLayout;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.io.File;
 import java.net.InetAddress;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.net.UnknownHostException;
 import javax.swing.JButton;
 import javax.swing.JFrame;
 import javax.swing.JLabel;
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JTextField; /*
  * 双向通信的服务端.
  */
 public class Server extends JFrame implements ActionListener {
 private    static String path;//接收文件的路径
 private    static String savepath;//保存文件的路径
     
         JPanel jp1, jp2, jp3,jp4;
         JLabel jl1 = null;
         JButton captureBtn, stopBtn, playBtn, saveBtn,sendBtn,setButton;
       //连接信息和录音信息
         JLabel linkLabel=null;
         JLabel rdLabel=null;
         JLabel ipLabel=null;
         //路径信息
         JTextField  repath,svpath;
         //定义初始音频类
        audioUtils server=null;
        //获取本地IP
        InetAddress ia=null;
        
        Socket s=null;
     
      // 构造函数
         public  Server() throws UnknownHostException {
             // 组件初始化
             jp1 = new JPanel();
             jp2 = new JPanel();
             jp3 = new JPanel();
             jp4=new JPanel();
             //文本框初始化
               repath=new JTextField("输入接收录音文件保存的路径");
                svpath=new JTextField("输入要保存的录音文件路径");
             //定义连接和录音提示
              linkLabel=new JLabel("未连接");
              rdLabel=new JLabel("");
              ipLabel=new JLabel("本地IP:"+ia.getLocalHost().getHostAddress());
             
              // 定义字体
             Font myFont = new Font("宋体", Font.BOLD, 30);
             jl1 = new JLabel("实时通信系统服务端");
             jl1.setFont(myFont);
         
             captureBtn = new JButton("开始录音");
             // 对开始录音按钮进行注册监听
             captureBtn.addActionListener(this);
             captureBtn.setActionCommand("captureBtn");
             // 对停止录音进行注册监听
             stopBtn = new JButton("停止录音");
             stopBtn.addActionListener(this);
             stopBtn.setActionCommand("stopBtn");
             // 对播放录音进行注册监听
             playBtn = new JButton("播放录音");
             playBtn.addActionListener(this);
             playBtn.setActionCommand("playBtn");
             // 对保存录音进行注册监听
             saveBtn = new JButton("保存录音");
             saveBtn.addActionListener(this);
             saveBtn.setActionCommand("saveBtn");
             //对发送录音进行注册监听
             sendBtn=new JButton("发送录音");
             sendBtn.addActionListener(this);
             sendBtn.setActionCommand("sendBtn");
             //对设置ip,路径等监听
             setButton=new JButton("保存设置");
             setButton.addActionListener(this);
             setButton.setActionCommand("setButton");
             
             
             this.add(jp1, BorderLayout.NORTH);
             this.add(jp2, BorderLayout.CENTER);
             this.add(jp3, BorderLayout.SOUTH);
             this.add(jp4,BorderLayout.NORTH);
             jp3.setLayout(null);
             jp3.setLayout(new GridLayout(1, 4, 10, 10));
             jp2.add(rdLabel);
             jp2.add(linkLabel);
             jp2.add(ipLabel);
             jp3.add(captureBtn);
             jp3.add(stopBtn);
             jp3.add(playBtn);
             jp3.add(saveBtn);
             jp3.add(sendBtn);
             jp4.add(svpath);
             jp4.add(repath);
             jp4.add(setButton);
             // 设置按钮的属性
             this.captureBtn.setEnabled(false);
             this.stopBtn.setEnabled(false);
             this.playBtn.setEnabled(false);
             this.saveBtn.setEnabled(false);
             this.sendBtn.setEnabled(false);
             // 设置窗口的属性
             this.setSize(700, 500);
             this.setTitle("服务端");
             this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             this.setLocationRelativeTo(null);
             this.setVisible(true);
             
             try {
                 server=new audioUtils();
                 //等待连接
                 ServerSocket ss=new ServerSocket(8888);
                 //阻塞方法,一直等待客户端接入
                 while(true){
                 //监听连接
                     
                      s=ss.accept();
                     JOptionPane.showMessageDialog(null, "连接成功....");
             
                     System.out.println("已经连接");
                     linkLabel.setText("已连接:");
                     //开启一个接收文件的线程
                     server.recied(s, new File(path));
                     
             }
                 
             }
             catch (Exception e) {
             e.printStackTrace();
             linkLabel.setText("未连接:");
             }
              
         }
             
         //事件
         public void actionPerformed(ActionEvent e) {
             if (e.getActionCommand().equals("captureBtn")) {
                 // 点击开始录音按钮后的动作
                 // 停止按钮可以启动
                 captureBtn.setEnabled(false);
                 stopBtn.setEnabled(true);
                 playBtn.setEnabled(false);
                 saveBtn.setEnabled(false);
                 sendBtn.setEnabled(false);
                 
                 // 调用录音的方法
                 capture();
                 rdLabel.setText("正在录音..");
             } else if (e.getActionCommand().equals("stopBtn")) {
                 // 点击停止录音按钮的动作
                 captureBtn.setEnabled(true);
                 stopBtn.setEnabled(false);
                 playBtn.setEnabled(true);
                 saveBtn.setEnabled(true);
                 if(s!=null)
                     sendBtn.setEnabled(true);    
                 
                 // 调用停止录音的方法
                 stop();
                 rdLabel.setText("完成录音..");
                 }
              else if (e.getActionCommand().equals("playBtn")) {
                 // 调用播放录音的方法
                 play();
             } else if (e.getActionCommand().equals("saveBtn")) {
                 // 调用保存录音的方法
                 rdLabel.setText("保存录音...");
                 save();
                 
             }else if(e.getActionCommand().equals("sendBtn")){
                 //调用发送录音的方法
                 rdLabel.setText("发送录音");
                 send();
                 
             }else if(e.getActionCommand().equals("setButton")){
                 
                  path=repath.getText().trim();
                  savepath=svpath.getText().trim();
                  if(new File(savepath).isDirectory())
                  {
                      savepath+="/"+System.currentTimeMillis()+".mp3";
                      this.captureBtn.setEnabled(true);
                  }else{
                      svpath.setText("文件路径不存在!");
                      return ;
                  }
                  
                  if(new File(path).isDirectory())
                  {
                      path+="/recied.mp3";
                  }else{
                      repath.setText("文件路径不存在!");
                      return ;
                  }
                  
               
                 this.setButton.setEnabled(false);
                  JOptionPane.showMessageDialog(null, "设置成功");
             }
 }
         
         //开始录音
         public void capture()        //录音代码
         {              server.capture();
         }
         
         // 停止录音
         public void stop() {
            server.stop();
         }
         
         // 播放录音
         public void play(){
         server.play();
         }        // 保存录音
         public void save() {
             // 取得录音输入流
     server.save(new File(savepath));
         }
         
     //发送录音到客户端(不保存到本地文件的发送)
         public void send()
         {
         server.send();
          
         }
         
             public static void main(String []args){
         try {
             Server ss=new Server();
         } catch (UnknownHostException e) {
             // TODO 自动生成的 catch 块
             e.printStackTrace();
         }
     }
 } 
2.客户端代码:
import javax.swing.*;
import java.awt.BorderLayout;
 import java.awt.Font;
 import java.awt.GridLayout;
 import java.awt.event.*;
 import java.io.*;
 import java.net.Socket;
 import java.net.UnknownHostException;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern; public class Client extends JFrame implements ActionListener {
 private    static String IP;//服务端的IP地址
 private    static int port=8888;//端口号
 private    static String path;//接收文件的路径
 private    static String savepath;//保存文件的路径
     
     //定义音频类
     audioUtils client=null;
     // 定义所需要的组件
     JPanel jp1, jp2, jp3,jp4;
     JLabel jl1 = null;
     JButton captureBtn, stopBtn, playBtn, saveBtn,sendBtn,linkBtn,delinkBtn,setButton;
     JTextField  iptxt,repath,svpath;
     JLabel linkLabel=null;
     JLabel rdLabel=null;
     private Socket s;
     // 构造函数
     public  Client() {
         
         //音频类初始化
        client=new audioUtils();
        //文本框初始化
        iptxt=new JTextField("输入要连接的IP地址");
        repath=new JTextField("输入接收录音文件保存的路径");
        svpath=new JTextField("输入要保存的录音文件路径");
         // 组件初始化
         jp1 = new JPanel();
         jp2 = new JPanel();
         jp3 = new JPanel();
         jp4=new JPanel();
         
         //定义连接和录音提示
          linkLabel=new JLabel("未连接");
          rdLabel=new JLabel("");
         // 定义字体
         Font myFont = new Font("宋体", Font.BOLD, 30);
         jl1 = new JLabel("实时通信系统客户端");
         jl1.setFont(myFont);
         captureBtn = new JButton("开始录音");
         // 对开始录音按钮进行注册监听
         captureBtn.addActionListener(this);
         captureBtn.setActionCommand("captureBtn");
         // 对停止录音进行注册监听
         stopBtn = new JButton("停止录音");
         stopBtn.addActionListener(this);
         stopBtn.setActionCommand("stopBtn");
         // 对播放录音进行注册监听
         playBtn = new JButton("播放录音");
         playBtn.addActionListener(this);
         playBtn.setActionCommand("playBtn");
         // 对保存录音进行注册监听
         saveBtn = new JButton("保存录音");
         saveBtn.addActionListener(this);
         saveBtn.setActionCommand("saveBtn");
         //对发送录音进行注册监听
         sendBtn=new JButton("发送录音");
         sendBtn.addActionListener(this);
         sendBtn.setActionCommand("sendBtn");
         //对连接录音进行注册监听
         linkBtn=new JButton("连接");
         linkBtn.addActionListener(this);
         linkBtn.setActionCommand("linkBtn");
         //对断开连接进行注册监听
         delinkBtn=new JButton("断开连接");
         delinkBtn.addActionListener(this);
         delinkBtn.setActionCommand("delinkBtn");
         //对设置ip,路径等监听
         setButton=new JButton("保存设置");
         setButton.addActionListener(this);
         setButton.setActionCommand("setButton");
         
         this.add(jp1, BorderLayout.NORTH);
         this.add(jp2, BorderLayout.CENTER);
         this.add(jp3, BorderLayout.SOUTH);
         this.add(jp4,BorderLayout.NORTH);
         jp3.setLayout(null);
         jp3.setLayout(new GridLayout(1, 4, 10, 10));
         jp4.add(iptxt);
         jp4.add(svpath);
         jp4.add(repath);
         jp4.add(setButton);
         jp2.add(rdLabel);
         jp2.add(linkBtn);
         jp2.add(delinkBtn);
         jp2.add(linkLabel);
         jp3.add(captureBtn);
         jp3.add(stopBtn);
         jp3.add(playBtn);
         jp3.add(saveBtn);
         jp3.add(sendBtn);
         // 设置按钮的属性
         this.linkBtn.setEnabled(false);
         this.delinkBtn.setEnabled(false);
         this.captureBtn.setEnabled(false);
         this.stopBtn.setEnabled(false);
         this.playBtn.setEnabled(false);
         this.saveBtn.setEnabled(false);
         this.sendBtn.setEnabled(false);
         this.setButton.setEnabled(true);
         // 设置窗口的属性
         this.setSize(700, 500);
         this.setTitle("客户端");
         this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         this.setLocationRelativeTo(null);
         this.setVisible(true);
     }    public void actionPerformed(ActionEvent e) {
         if (e.getActionCommand().equals("captureBtn")) {
             // 点击开始录音按钮后的动作
             // 停止按钮可以启动
             captureBtn.setEnabled(false);
             stopBtn.setEnabled(true);
             playBtn.setEnabled(false);
             saveBtn.setEnabled(false);
             sendBtn.setEnabled(false);
             
             // 调用录音的方法
             capture();
             rdLabel.setText("正在录音..");
         } else if (e.getActionCommand().equals("stopBtn")) {
             // 点击停止录音按钮的动作
             captureBtn.setEnabled(true);
             stopBtn.setEnabled(false);
             playBtn.setEnabled(true);
             saveBtn.setEnabled(true);
             if(!linkBtn.isEnabled()){
                 sendBtn.setEnabled(true);
             }
             
             // 调用停止录音的方法
             stop();
             rdLabel.setText("完成录音..");
         } else if (e.getActionCommand().equals("playBtn")) {
             // 调用播放录音的方法
             play();
         } else if (e.getActionCommand().equals("saveBtn")) {
             // 调用保存录音的方法
             rdLabel.setText("保存录音..");
             save();
         }else if(e.getActionCommand().equals("sendBtn")){
             rdLabel.setText("发送录音..");
             send();
         }
         else if(e.getActionCommand().equals("linkBtn")){
             linkBtn.setEnabled(false);
             delinkBtn.setEnabled(true);
             if(saveBtn.isEnabled())
             sendBtn.setEnabled(true);
             link();
             if(s.isConnected())
             linkLabel.setText("已连接:");
         }
         else if(e.getActionCommand().equals("delinkBtn")){
             delinkBtn.setEnabled(false);
             linkBtn.setEnabled(true);
             sendBtn.setEnabled(false);
             delink();
             linkLabel.setText("未连接:");
         }else if(e.getActionCommand().equals("setButton")){
         
             //校验ip地址
             Pattern p = Pattern.compile("^((25[0-5]|2[0-4]\\d|[1]{1}\\d{1}\\d{1}|[1-9]{1}\\d{1}|\\d{1})($|(?!\\.$)\\.)){4}$");
             Matcher m = p.matcher(iptxt.getText());
             boolean b = m.matches();
             if(!b){
                 iptxt.setText("IP输入不合法");
                 return ;
             }
              IP=iptxt.getText().trim();
              
              path=repath.getText().trim();
              savepath=svpath.getText().trim();
              if(new File(savepath).isDirectory())
              {
                  savepath+="/"+System.currentTimeMillis()+".mp3";
                  this.captureBtn.setEnabled(true);
              }else{
                  svpath.setText("文件路径不存在!");
                  return ;
              }
              
              if(new File(path).isDirectory())
              {
                  path+="/recied.mp3";
              }else{
                  repath.setText("文件路径不存在!");
                  return;
              }
              
            
              this.linkBtn.setEnabled(true);
             this.setButton.setEnabled(false);
              JOptionPane.showMessageDialog(null, "设置成功");
         }
     }
     
     //连接到服务端
     public void link()
     {
         //初始化一个套接字
          try {
                 s=new Socket(IP,port);
             
            
             //开启一个接收文件的线程
             client.recied(s, new File(path));
             
         } catch (UnknownHostException e) {
             System.out.println("连接失败");
         } catch (IOException e) {
             // TODO 自动生成的 catch 块
             e.printStackTrace();
         }
     }
     
     /*
      * 断开连接
      * (必须再连接之后再调用此方法,否则控制台会打印当前并无连接。)
      * throws IOExcpetion e(关闭异常失败)
      */
     public void delink() {
          if(s.isClosed())System.out.println("当前并无连接");
         try {
             s.close();
         } catch (IOException e) {
             // TODO 自动生成的 catch 块
             e.printStackTrace();
         }
     }
     
 //录音
     public void capture(){
         client.capture();
     }
         // 停止录音
 public void stop(){
     client.stop();
 }//播放录音(默认播放刚刚完成的录音)
 public void play(){
     client.play();
 }    // 保存录音
 public void save(){
     client.save(new File(savepath));
 }
     
 //发送录音到服务端(不保存到本地的发送)
     public void send(){
         client.send();
     }
 //     public static void main(String[] args) {
         // 创造一个实例
         Client tc=new Client();
     } }
 
3。音频工具类
//音频工具类。需要实例化。
 import java.io.BufferedInputStream;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.Socket;
 import java.net.UnknownHostException;import javax.sound.sampled.*;
 import javax.swing.JOptionPane; class audioUtils
 {
         // 定义录音格式
     private    AudioFormat af = null;
         // 定义目标数据行,可以从中读取音频数据,该 TargetDataLine 接口提供从目标数据行的缓冲区读取所捕获数据的方法。
     private    TargetDataLine td = null;
         // 定义源数据行,源数据行是可以写入数据的数据行。它充当其混频器的源。应用程序将音频字节写入源数据行,这样可处理字节缓冲并将它们传递给混频器。
     private    SourceDataLine sd = null;
         // 定义字节数组输入输出流
     private    ByteArrayInputStream bais = null;
     private    ByteArrayOutputStream baos = null;
         // 定义音频输入流
     private    AudioInputStream ais = null;
         // 定义停止录音的标志,来控制录音线程的运行
     private    Boolean stopflag = false;
     private    Socket s=null;
     
     //默认的AudioFormat
     private AudioFormat.Encoding encoding = AudioFormat.Encoding.
             PCM_SIGNED ;
     private     float rate = 16000f;
     private         int sampleSize = 16;
     private         String signedString = "signed";
     private         boolean bigEndian = true;
     private         int channels = 2;
     
             
     /*接收文件
      * @param socket(套接字),file文件
      * 
      */
     public  void recied(Socket s,File file)
     {
             
             //开启一个接收文件的线程
             recied r=new recied(s,file);
             Thread t1=new Thread(r);
              t1.start();
         
     }
     
     
     
     /*停止录音
      * 
      */
     public void stop() {
         stopflag = true;
         //之前的源音频数据流要关了
         if(td!=null)
             {
             td.close();
             }
     }
     
     /*
      * 播放语音(没流默认播放当前录音流)
      */
         public void play(){
             Thread t1=new Thread(new play(ais));
             t1.start();
         }
     /*
      * 有流播放传入的流
      * @param ais(音频输入流)
      */
         public void play(AudioInputStream ais){
             Thread t1=new Thread(new play(ais));
             t1.start();
         }
         
 /*
  * 保存文件
  * @param file(本地文件,若文件不存在会自动创建)    
  */
         public void save(File file) {
             // 取得录音输入流
             af = getAudioFormat();
             byte audioData[] = baos.toByteArray();
             bais = new ByteArrayInputStream(audioData);
             ais = new AudioInputStream(bais, af, audioData.length
                     / af.getFrameSize());
             
             // 写入文件
             try {
                 
                 if (!file.exists()) {// 如果文件不存在,则创建该文件
                     file.createNewFile();
                 }
         
               
                 AudioSystem.write(ais, AudioFileFormat.Type.WAVE, file);
             } catch (Exception e) {
                 e.printStackTrace();
             } finally {
                 // 关闭流
                 try {
                     if (bais != null) {
                         bais.close();
                     }
                     if (ais != null) {
                         ais.close();
                     }
                 } catch (Exception e) {
                     e.printStackTrace();
                 }
             }
         }
     
     
     /*
      * 开始录音
      */
         public  void capture()        //录音代码
         {
             try {
                 af = getAudioFormat();
                 DataLine.Info info = new DataLine.Info(TargetDataLine.class,af);
                 td = (TargetDataLine)(AudioSystem.getLine(info));
                 
                 td.open(af);
                 td.start();
                 Record record = new Record();
                 Thread t1 = new Thread(record);
                 t1.start();
             
             } catch (LineUnavailableException ex) {
                 ex.printStackTrace();
                 return;
             }
         }
         /*
          * 发送录音(需要在连接后使用,否则会抛RuntimeException异常)
          * throws 
          */
         public void send()
         {
             Thread t1=new Thread(new Send());
             t1.start();
             if(s.isClosed()){
                 throw new RuntimeException();
             }
          
         }
         
         // 录音类,因为要用到MyRecord类中的变量,所以将其做成内部类
         class Record implements Runnable    // 录音线程    
         {
             byte bts[] = new byte[10000];            public void run() {    
                 baos = new ByteArrayOutputStream();        
                 try {
                     System.out.println("客户端正在录音...");
                     stopflag = false;
                     while(stopflag != true)
                     {
                         int cnt = td.read(bts, 0, bts.length);
                         if(cnt > 0)
                         {
                             baos.write(bts, 0, cnt);
                         }
                     }
                     af = getAudioFormat();
                     byte audioData[] = baos.toByteArray();
                     bais = new ByteArrayInputStream(audioData);
                     ais = new AudioInputStream(bais, af, audioData.length
                             / af.getFrameSize());
                        //查看数据
                     System.out.println("长度:"+ais.getFrameLength()+"最大"+ais.available());
                 } catch (Exception e) {
                     e.printStackTrace();
                 }finally{
                     try {
                         if(baos != null)
                         {
                             baos.close();
                         }    
                         if(bais!=null){
                             bais.close();
                         }
                    } catch (IOException e) {
                         e.printStackTrace();
                     }finally{
                         
                         td.drain();
                         td.close();
                     }
                 }
             }
             
         }
         
         // 设置AudioFormat的参数
         public AudioFormat getAudioFormat()    //录音格式
         {
             
             return new AudioFormat(encoding, rate, sampleSize, channels,(sampleSize / 8) * channels, rate, bigEndian);
         }
         /*
          * 设置AduioFomat
          */
         public void setAudioFormat
 (AudioFormat.Encoding encoding,float rate,int sampleSize,String signedString,boolean bigEndian,int channels)
         {
             this.encoding = encoding;
                     this.rate = 16000f;
                     this. sampleSize = 16;
                     this.signedString = "signed";
                 this. bigEndian = true;
                     this. channels = 2;
         }        
        //播放线程类
         class play implements Runnable{
           private AudioInputStream ais;
             public play(AudioInputStream ais){
               this.ais=ais;
           }
             @Override
             public void run() {
                 // TODO 自动生成的方法存根
             
                 playAudio(ais);
                 
             }
             
             //接收一个音频流
             public  void playAudio(AudioInputStream ais)
             {
                 try{
                     AudioFormat baseFormat=ais.getFormat();
                     
                     DataLine.Info info=new DataLine.Info(SourceDataLine.class, baseFormat);
                     
                     SourceDataLine line=(SourceDataLine)AudioSystem.getLine(info);
                     System.out.println("正在播放录音");
                     line.open(baseFormat); 
                     line.start();
                     int BUFFER_SIZE=4000*4;
                     int intBytes=0;
                     int outBytes;
                     byte[] audioData=new byte[BUFFER_SIZE];
                     while(intBytes!=-1)
                     {
                         intBytes=ais.read(audioData, 0, BUFFER_SIZE);
                         if(intBytes>=0)
                             outBytes=line.write(audioData, 0, intBytes);                
                     }
                 }catch(Exception e)
                 {
                     e.printStackTrace();
                 }
                 finally{
                     try {
                         ais.close();
                     } catch (IOException e) {
                         // TODO 自动生成的 catch 块
                         System.out.println("关流失败");
                     }
                 }
             }
             
         }
         
         //发送文件的线程类(不用保存到本地文件直接发送)
         class Send implements Runnable{
      
             public void run()
             {
                 send();
           
              }
             
             private  void send(){
                  try {
                      
                         af = getAudioFormat();
                         
                         byte audioData[] = baos.toByteArray();
                         
                         bais = new ByteArrayInputStream(audioData);
                     
                         ais = new AudioInputStream(bais, af, audioData.length
                                 / af.getFrameSize());
                     
                         if(s!=null){
                         //将输入流写入服务端的输出流
                             s.getOutputStream().flush();
                         AudioSystem.write(ais, AudioFileFormat.Type.WAVE, s.getOutputStream());
                         }
                         
                         System.out.println("发送到服务端");
                         ais.close();
                  }
                              
                  catch (UnknownHostException e) {
                     // TODO 自动生成的 catch 块
                     
                     e.printStackTrace();
                 } catch (IOException e) {
                     // TODO 自动生成的 catch 块
                     e.printStackTrace();
                 }
             }
         }
         
         //收语音的线程,并播放的类
             class recied implements Runnable{
                 InputStream in=null;
                 File file=null;
                 public recied(Socket socket,File file){
                     s=socket;
                     this.file=file;
                 }
                 @Override
                 public void run() {
                     // TODO 自动生成的方法存根
                     try{
                         while(true)
                         {
                         if (!file.exists()) {// 如果文件不存在,则创建该目录
                             file.createNewFile();
                         }
                         
                         //获得客户端的读取流(阻塞)
                         in=s.getInputStream();                        //这个网络流不允许读写头来回移动,也就不允许mark/reset机制需要buffer包起来。
                         BufferedInputStream bufin=new BufferedInputStream(in);    
                         
                     //获取到客户端传过来的输入流,并转化为录音输入流
                         ais = AudioSystem.getAudioInputStream(bufin);
                     //写入本地文件.
                      AudioSystem.write(ais, AudioFileFormat.Type.WAVE, file);
                     
                      System.out.println("收到录音..");
                      JOptionPane.showMessageDialog(null, "收到录音....");
                       AudioInputStream aui=AudioSystem.getAudioInputStream(file);
                     
                       
                      //播放收到的声音
                      play(aui);
                     
                         }
                     }catch(Exception e){
                         e.getStackTrace();
                     }
                     
                 }
                 
             }
 }