我正在嘗試編寫一個Java語音聊天應用程序,並且已經實現了回聲功能,但是當嘗試連接多個客戶端時,我被卡住了。我知道你不能迭代套接字並將數據發送給所有連接的人,而不會混淆數據。 (我試過了,聽起來不像它應該如何)。我不太確定該怎麼做,而且我正在使用一個非常簡單的字節緩衝回顯服務器作爲服務器(我想要執行混合)。我還有一個客戶端,可以接收麥克風輸入,將其發送到服務器,從服務器獲取數據,並從揚聲器播放數據。Java語音聊天 - Mixdown傳入數據單輸出
注意:客戶端由2個類(Program和SoundReceiver)組成。我正在使用javax.sound.sampled庫。
回聲服務器:http://pastebin.com/c9KiaTpJ
import java.net.*;
import java.io.*;
import java.util.*;
public class Echo
{
public static void main(String[] args) throws Exception
{
ServerSocket serverSocket = new ServerSocket(3000);
while(true){Thread echoThread = new Thread(new EchoThread(serverSocket.accept()));
echoThread.start();}
}
}
class EchoThread implements Runnable
{
public static Collection<Socket> sockets = new ArrayList<Socket>();
Socket connection = null;
DataInputStream dataIn = null;
DataOutputStream dataOut = null;
public EchoThread(Socket conn) throws Exception
{
connection = conn;
dataIn = new DataInputStream(connection.getInputStream());
dataOut = new DataOutputStream(connection.getOutputStream());
sockets.add(connection);
}
public void run()
{
int bytesRead = 0;
byte[] inBytes = new byte[1];
while(bytesRead != -1)
{
try{bytesRead = dataIn.read(inBytes, 0, inBytes.length);}catch (IOException e){}
if(bytesRead >= 0)
{
sendToAll(inBytes, bytesRead);
}
}
sockets.remove(connection);
}
public static void sendToAll(byte[] byteArray, int q)
{
Iterator<Socket> sockIt = sockets.iterator();
while(sockIt.hasNext())
{
Socket temp = sockIt.next();
DataOutputStream tempOut = null;
try
{
tempOut = new DataOutputStream(temp.getOutputStream());
} catch (IOException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
try{tempOut.write(byteArray, 0, q);}catch (IOException e){}
}
}
}
客戶端程序類:http://pastebin.com/v24CYwXE
import java.io.DataOutputStream;
import java.net.*;
import javax.sound.sampled.*;
public class Program
{
public static void main(String[] args) throws Exception
{
AudioFormat af = new AudioFormat(8000.0f,8,1,true,false);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, af);
TargetDataLine microphone = (TargetDataLine)AudioSystem.getLine(info);
microphone.open(af);
Socket conn = new Socket("localhost",3000);
microphone.start();
DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
int bytesRead = 0;
byte[] soundData = new byte[1];
Thread inThread = new Thread(new SoundReceiver(conn));
inThread.start();
while(bytesRead != -1)
{
bytesRead = microphone.read(soundData, 0, soundData.length);
if(bytesRead >= 0)
{
dos.write(soundData, 0, bytesRead);
}
}
System.out.println("IT IS DONE.");
}
}
客戶SoundReceiver類:http://pastebin.com/2tt0Jucv
import java.net.*;
import java.io.*;
import javax.sound.sampled.*;
public class SoundReceiver implements Runnable
{
Socket connection = null;
DataInputStream soundIn = null;
SourceDataLine inSpeaker = null;
public SoundReceiver(Socket conn) throws Exception
{
connection = conn;
soundIn = new DataInputStream(connection.getInputStream());
AudioFormat af = new AudioFormat(8000.0f,8,1,true,false);
DataLine.Info info = new DataLine.Info(SourceDataLine.class, af);
inSpeaker = (SourceDataLine)AudioSystem.getLine(info);
inSpeaker.open(af);
}
public void run()
{
int bytesRead = 0;
byte[] inSound = new byte[1];
inSpeaker.start();
while(bytesRead != -1)
{
try{bytesRead = soundIn.read(inSound, 0, inSound.length);} catch (Exception e){}
if(bytesRead >= 0)
{
inSpeaker.write(inSound, 0, bytesRead);
}
}
}
}
基本上,我想合併所有傳入字節在保持的同時保存到一個字節數組每個人的聲音都很大(就像一個3路電話一樣)。
個人(我知道我不是唯一的一個),我往往懶得點擊這樣的鏈接。在你的問題中插入你的代碼通常是一個好主意。如果你覺得將所有代碼內聯太多,創建一個[SSCCE](http://sscce.org),如果可能的話,總是一個好主意。 – Jeffrey 2012-07-24 02:29:33
有沒有一種更簡單的方法來發布代碼比在每行之前製作4個空格? – zgillis 2012-07-24 02:50:48
看起來這與套接字沒有多大關係,但與聲音處理有關。 – 2012-07-24 03:01:45