先上效果圖
Demo說(shuō)明
有三個(gè)模擬器淑廊,通過(guò)Socket鸽捻,將信息相互發(fā)送到對(duì)方的設(shè)備上凳鬓。其中的認(rèn)證客戶端是指將此客戶端的信息傳到服務(wù)端茁肠,以便在客戶端一對(duì)一發(fā)送消息時(shí),服務(wù)端可以找到相應(yīng)的設(shè)備缩举。
定義客戶端代碼
public class ClientConnector {
private Socket mClient;
/**
* 服務(wù)端的ip
*/
private String mDstName;
/**
* 服務(wù)端端口號(hào)
*/
private int mDesPort;
private ConnectLinstener mListener;
public ClientConnector(String dstName, int dstPort) {
this.mDstName = dstName;
this.mDesPort = dstPort;
}
/**
* 與服務(wù)端進(jìn)行連接
*
* @throws IOException
*/
public void connect() throws IOException {
if (mClient == null) {
mClient = new Socket(mDstName, mDesPort);
}
//獲取其他客戶端發(fā)送過(guò)來(lái)的數(shù)據(jù)
InputStream inputStream = mClient.getInputStream();
byte[] buffer = new byte[1024];
int len = -1;
while ((len = inputStream.read(buffer)) != -1) {
String data = new String(buffer, 0, len);
//通過(guò)回調(diào)接口將獲取到的數(shù)據(jù)推送出去
if (mListener != null) {
mListener.onReceiveData(data);
}
}
}
/**
* 認(rèn)證方法垦梆,這個(gè)方法是用來(lái)進(jìn)行客戶端一對(duì)一發(fā)送消息的
* 在實(shí)際項(xiàng)目中進(jìn)行即時(shí)通訊時(shí)都需要進(jìn)行登錄,這里就是
* 模擬客戶端的賬號(hào)
*
* @param authName
*/
public void auth(String authName) throws IOException {
if (mClient != null) {
//將客戶端賬號(hào)發(fā)送給服務(wù)端蚁孔,讓服務(wù)端保存
OutputStream outputStream = mClient.getOutputStream();
//模擬認(rèn)證格式奶赔,以#開(kāi)頭
outputStream.write(("#" + authName).getBytes());
}
}
/**
* 將數(shù)據(jù)發(fā)送給指定的接收者
*
* @param receiver 信息接數(shù)者
* @param data 需要發(fā)送的內(nèi)容
*/
public void send(String receiver, String data) throws IOException {
OutputStream outputStream = mClient.getOutputStream();
//模擬內(nèi)容格式:receiver+ # + content
outputStream.write((receiver + "#" + data).getBytes());
}
/**
* 斷開(kāi)連接
*
* @throws IOException
*/
public void disconnect() throws IOException {
if (mClient != null) {
mClient.close();
mClient = null;
}
}
public void setOnConnectLinstener(ConnectLinstener linstener) {
this.mListener = linstener;
}
/**
* 數(shù)據(jù)接收回調(diào)接口
*/
public interface ConnectLinstener {
void onReceiveData(String data);
}
}
定義服務(wù)端代碼
public class SocketServer {
/**
* 用來(lái)保存不同的客戶端
*/
private static Map<String, Socket> mClients = new LinkedHashMap<>();
public static void main(String[] args) {
int port = 9999;
try {
//創(chuàng)建服務(wù)器
ServerSocket serverSocket = new ServerSocket(port);
while (true) {
//獲取客戶端的連接
final Socket socket = serverSocket.accept();
new Thread(new Runnable() {
@Override
public void run() {
try {
//讀取從客戶端發(fā)送過(guò)來(lái)的數(shù)據(jù)
InputStream inputStream = socket.getInputStream();
byte[] buffer = new byte[1024];
int len = -1;
while ((len = inputStream.read(buffer)) != -1) {
String data = new String(buffer, 0, len);
//先認(rèn)證客戶端
if (data.startsWith("#")) {
mClients.put(data, socket);
} else {
//將數(shù)據(jù)發(fā)送給指定的客戶端
String[] split = data.split("#");
Socket c = mClients.get("#" + split[0]);
OutputStream outputStream = c.getOutputStream();
outputStream.write(split[1].getBytes());
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}