チャットルームサービス
前言
これは私がjavaで書いたAndroidチャットルームプロジェクトのサービス端で、もちろんjavaプロジェクトにも使えます.ここには2つのサービス端が書かれていて、1つは複数の人のチャットしか実現していません.1つは複数の人で、1対1です.
Androidクライアントソースサービス1(複数人チャット) サービス端末2(複数チャット+1対1) 質問:私たちは複数のチャットでArrayListの集合で各接続上のSocketオブジェクトを格納していますが、明らかに私がデータを転送するSocketだと判断できません.
解決策:ArrayListをHashMapに変更し、キーはユーザーを識別する情報を格納し、値はSocketを格納し、送信時にキーによってその時のSocketと接続するかどうかを判断する
例えば私のキー転送のipは、ipに基づいて接続が確立されているかどうかを判断します(明らかに1台のコンピュータで相互に転送できません(HashMapは重複していません))
反省:
このような一対一の限界は明らかに大きく、ipでマッチングするしかないが、idで人を探したいならどうやってマッチングするのだろうか.登録ログインインタフェースを書くことができると思います.ログイン時にユーザーのSocketを取得することができ、HashMapでメンテナンスし、キーでidを入力し、値はSocketオブジェクトに入力します.このようにログインしている限り、私たちのHashMapに転送され、1対の一時が必要であればidでチャットにマッチすることができます.
これは私がjavaで書いたAndroidチャットルームプロジェクトのサービス端で、もちろんjavaプロジェクトにも使えます.ここには2つのサービス端が書かれていて、1つは複数の人のチャットしか実現していません.1つは複数の人で、1対1です.
Androidクライアントソース
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
public class Run2 {
private final static int PORT = 12345; //
public static ArrayList<Socket> list ;
public static void main(String[] args) throws IOException {
//
new Thread(new startServer()).start();
}
static class startServer implements Runnable{
@Override
public void run() {
try {
ServerSocket server = new ServerSocket(PORT);
list = new ArrayList<>();
while (true) {
Socket client = server.accept();
System.out.println(client);
// Socket List
list.add(client);
//
// , Socket,
// List ,
new choicesend2(client,list).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class choicesend2 extends Thread {
private Socket socket;
private DataOutputStream dos;
private DataInputStream dis;
public ArrayList<Socket> list;
public choicesend2(Socket socket, ArrayList<Socket> list) {
this.socket = socket;
this.list = list;
}
@Override
public void run() {
try {
//
dis = new DataInputStream(socket.getInputStream());
// ,
while (true) {//
// ,
String title;
String name;
String ip;
char[] temp = new char[200];
int len = 0;
char c = 0;
while ((c = dis.readChar()) != '\t') {
temp[len] = c;
len++;
}
title = new String(temp, 0, len);
len = 0;
while ((c = dis.readChar()) != '\t') {
temp[len] = c;
len++;
}
name = new String(temp, 0, len);
len = 0;
while ((c = dis.readChar()) != '\t') {
temp[len] = c;
len++;
}
ip = new String(temp, 0, len);
System.out.println(ip);
// , Socket,
for (Socket socket : list) {
if(socket==this.socket) //
continue;
// dos Socket,
dos = new DataOutputStream(socket.getOutputStream());
try {
dos.writeChars(title);
dos.writeChar('\t');
dos.writeChars(name);
dos.writeChar('\t');
dos.writeInt(0);
dos.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}catch (IOException e) {
e.printStackTrace();
}
}
}
解決策:ArrayListをHashMapに変更し、キーはユーザーを識別する情報を格納し、値はSocketを格納し、送信時にキーによってその時のSocketと接続するかどうかを判断する
例えば私のキー転送のipは、ipに基づいて接続が確立されているかどうかを判断します(明らかに1台のコンピュータで相互に転送できません(HashMapは重複していません))
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
public class Run {
private final static int PORT = 12345;
public static ArrayList<Socket> list ;
public static HashMap<String,Socket> hs;
public static void main(String[] args) throws IOException {
new Thread(new startServer()).start();
}
static class startServer implements Runnable{
@Override
public void run() {
try {
ServerSocket server = new ServerSocket(PORT);
hs = new HashMap<>();
while (true) {
Socket client = server.accept();
System.out.println(client);
hs.put(client.getInetAddress().toString(),client);
new choicesend(client,hs).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class choicesend extends Thread {
private Socket socket;
private String key;
private DataOutputStream dos;
private DataInputStream dis;
public HashMap<String,Socket> hs;
public choicesend(Socket socket, HashMap<String,Socket> hs) {
this.socket = socket;
this.hs = hs;
}
@Override
public void run() {
try {
dis = new DataInputStream(socket.getInputStream());
while (true) {//
String title;
String name;
// ip, HashMap
String ip;
char[] temp = new char[200];
int len = 0;
char c = 0;
while ((c = dis.readChar()) != '\t') {
temp[len] = c;
len++;
}
title = new String(temp, 0, len);
len = 0;
while ((c = dis.readChar()) != '\t') {
temp[len] = c;
len++;
}
name = new String(temp, 0, len);
len = 0;
while ((c = dis.readChar()) != '\t') {
temp[len] = c;
len++;
}
ip = new String(temp, 0, len);
System.out.println(ip);
// 255.255.255.255
if(ip.equals("255.255.255.255")){
for(String sendip : hs.keySet()){
System.out.println(sendip+" ip");
Socket socket = hs.get(sendip);
dos = new DataOutputStream(socket.getOutputStream());
try {
// System.out.println(" ");
dos.writeChars(title);
dos.writeChar('\t');
dos.writeChars(name);
dos.writeChar('\t');
dos.writeInt(0);
dos.flush();
} catch (IOException e) {
//list.remove(socket);
e.printStackTrace();
}
}
}
// ip HashMap
else{
for(String sendip : hs.keySet()){
// System.out.println(sendip+" ip");
// client.getInetAddress().toString() ip “/”,
sendip = sendip.substring(1,sendip.length());
// Socket
if(ip.equals(sendip)){
Socket socket = hs.get(sendip);
if(socket!=null)
dos = new DataOutputStream(socket.getOutputStream());
try {
System.out.println(" ");
dos.writeChars(title);
dos.writeChar('\t');
dos.writeChars(name);
dos.writeChar('\t');
dos.writeInt(1);
dos.flush();
} catch (IOException e) {
// list.remove(socket);
e.printStackTrace();
}
}
}
}
}
}catch (IOException e) {
e.printStackTrace();
}
}
}
反省:
このような一対一の限界は明らかに大きく、ipでマッチングするしかないが、idで人を探したいならどうやってマッチングするのだろうか.登録ログインインタフェースを書くことができると思います.ログイン時にユーザーのSocketを取得することができ、HashMapでメンテナンスし、キーでidを入力し、値はSocketオブジェクトに入力します.このようにログインしている限り、私たちのHashMapに転送され、1対の一時が必要であればidでチャットにマッチすることができます.