Androidチャットルーム
12214 ワード
最近ネットのプログラミングを研究していて、とても面白いと感じて、それから游んでチャットルームを作って游びたいです.このチャットルームはChatRoomと呼ばれ、TCP通信ベースのチャットルームで、いくつかのMaterial Designのコントロールを使っています.これまでプロジェクトを急いでいたので、Material Designを勉強する時間がありませんでした(実は時間がないわけではありません.面倒なことがあるので、遅れています).スタジオの昭兄は私に、あなたの基礎工はしっかりしていないと言っていました.へへ.
TCP紹介
TCPは信頼性が高く、接続しなければ通信できないプロトコルです.
接続しなければ通信できないため、TCP通信はクライアントとサーバ端を厳格に区別し、クライアントがサーバ端に接続してこそ通信を実現することができ、サーバ端はクライアントに接続できず、事前に起動し、クライアントの要求を待つ必要がある.
再送メカニズムを使用して、データ伝送の信頼性を保証します.(送信後、確認メッセージが必要です.そうでなければ再送します)
図面
ChatRoom
さあ、辛さをたくさん話して、ChatRoomがどのように実現したのか見てみましょう.まず効果を見てみましょう.
サーバ側
以上のコードを書き終わると、サーバー側は基本的に完成しましたが、実は今、私たちはチャットルームを游ぶことができます.複数のcmdを開き、telnet localhost 30000を入力するとサーバーに接続でき、黒いボックスの下でチャットできます.
クライアント
メインインタフェース、サーバーのIPとチャットの中で表示する名前を入力します
インタフェースに入る
チャットインタフェース
に注意
サーバIPの表示
cmdを開いて、ipconfigを入力すると、自機のIP設定が見えます.無線LANでwifiに適しています.ここのIPv 4アドレスはサーバーのIPです.
携帯電話がサーバーに接続できない
シミュレータはサーバーに接続できますが、携帯電話が接続できない場合はどうすればいいですか?ネット上では携帯電話は外網だと言っていますが、内網にアクセスできない問題は、携帯電話とパソコンを1つのwifiと一緒にすればいいです.
TCP紹介
TCPは信頼性が高く、接続しなければ通信できないプロトコルです.
接続しなければ通信できないため、TCP通信はクライアントとサーバ端を厳格に区別し、クライアントがサーバ端に接続してこそ通信を実現することができ、サーバ端はクライアントに接続できず、事前に起動し、クライアントの要求を待つ必要がある.
再送メカニズムを使用して、データ伝送の信頼性を保証します.(送信後、確認メッセージが必要です.そうでなければ再送します)
図面
ChatRoom
さあ、辛さをたくさん話して、ChatRoomがどのように実現したのか見てみましょう.まず効果を見てみましょう.
サーバ側
/**
* Created by kn on 2016/5/24.
*
*
*/
public class MyServerSocket {
public static void main(String args[]){
new ServerListener().start();
}
}
/**
* Created by kn on 2016/5/24.
*
*
*/
public class ServerListener extends Thread {
@Override
public void run() {
try {
// port:1~65535
ServerSocket serverSocket = new ServerSocket(30000);
while(true){
//
Socket socket = serverSocket.accept();
//
System.out.println(" 30000 ");
// socket
ChatSocket chatSocket = new ChatSocket(socket);
chatSocket.start();
ChatManager.getInstance().add(chatSocket);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* Created by kn on 2016/5/24.
*
*
*/
public class ChatSocket extends Thread {
Socket socket;
public ChatSocket(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
BufferedReader br = new BufferedReader(
new InputStreamReader(socket.getInputStream(), "UTF-8"));
String line = null;
while ((line = br.readLine()) != null) {
ChatManager.getInstance().publish(this, line);
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
*
* @param message
*/
public void showMessage(String message) {
try {
socket.getOutputStream().write((message + "
").getBytes("UTF-8"));
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* socket
* @return
*/
public boolean isSocketClosed(){
return socket.isClosed();
}
}
/**
* Created by kn on 2016/5/24.
*
*
*/
public class ChatManager {
private static ChatManager instance = new ChatManager();
//
Vector vector = new Vector<>();
private ChatManager() {
}
/**
*
* @return
*/
public static ChatManager getInstance() {
if (instance == null) {
synchronized (ChatManager.class) {
if (instance == null) {
instance = new ChatManager();
}
}
}
return instance;
}
/**
*
*
* @param chatSocket
*/
public void add(ChatSocket chatSocket) {
vector.add(chatSocket);
}
/**
*
* @param chatSocket
* @param message
*/
public void publish(ChatSocket chatSocket, String message) {
//
for (int i = 0; i < vector.size(); i++) {
ChatSocket mChatSocket = vector.get(i);
//
if (!chatSocket.equals(mChatSocket)) {
//
if (mChatSocket.isSocketClosed()) {
vector.remove(i);
} else {
mChatSocket.showMessage(message);
}
}
}
}
}
以上のコードを書き終わると、サーバー側は基本的に完成しましたが、実は今、私たちはチャットルームを游ぶことができます.複数のcmdを開き、telnet localhost 30000を入力するとサーバーに接続でき、黒いボックスの下でチャットできます.
クライアント
メインインタフェース、サーバーのIPとチャットの中で表示する名前を入力します
インタフェースに入る
public class MainActivity extends AppCompatActivity {
MaterialEditText metName;//
MaterialEditText metIP;// IP
ImageView ivAvatar;//
ButtonFlat btnEnter;//
ProgressBar progressBar;//
FrameLayout flProgressBar;
public static Socket socket = null;
final static int SUCCESS = 0x01;//
final static int FAILURE = 0x02;//
final static int TIMEOUT = 0x03;//
final static int UN_KNOWN_HOST = 0x04;//
private BufferedWriter writer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
metName = (MaterialEditText) findViewById(R.id.met_name);
metIP = (MaterialEditText) findViewById(R.id.met_ip);
ivAvatar = (ImageView) findViewById(R.id.iv_avatar);
btnEnter = (ButtonFlat) findViewById(R.id.btn_enter);
progressBar = (ProgressBar) findViewById(R.id.progress);
flProgressBar = (FrameLayout) findViewById(R.id.fl_progress);
metName.setText("kntryer");
metIP.setText("192.168.1.101");
btnEnter.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
enterChatRoom();
}
});
}
private void enterChatRoom() {
// ip
final String ipString = metIP.getText().toString().trim();
new Thread(new Runnable() {
@Override
public void run() {
try {
socket = new Socket();
socket.connect(new InetSocketAddress(ipString, 30000), 5000);
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
handler.sendEmptyMessage(SUCCESS);
} catch (SocketTimeoutException e) {
// UI
handler.sendEmptyMessage(TIMEOUT);
e.printStackTrace();
} catch (UnknownHostException e) {
handler.sendEmptyMessage(UN_KNOWN_HOST);
e.printStackTrace();
} catch (IOException e) {
handler.sendEmptyMessage(FAILURE);
e.printStackTrace();
}
}
}).start();
}
Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case SUCCESS:
String name = metName.getText().toString();
try {
if (writer != null) {
writer.write("system," + name + " enter ChatRoom
");
writer.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
Intent intent = new Intent(MainActivity.this, ChatActivity.class);
intent.putExtra("name", name);
startActivity(intent);
break;
case FAILURE:
showIsOpenWifi("Please check whether the network is open or not.");
break;
case TIMEOUT:
showIsOpenWifi("SocketTimeoutException");
break;
case UN_KNOWN_HOST:
showIsOpenWifi("UnknownHostException");
break;
}
return false;
}
});
private void showIsOpenWifi(String message) {
new SnackBar(this, message, "Yes", new View.OnClickListener() {
@Override
public void onClick(View v) {
// WiFi,
}
}).show();
}
}
チャットインタフェース
/**
* Created by kn on 2016/5/24.
*/
public class ChatActivity extends AppCompatActivity {
ButtonFlat btnSent;//
MaterialEditText metMsg;//
ListView lvMsg;//
ArrayList msgList = new ArrayList<>();//
MessageAdapter adapter;
Socket socket;
String name;//
BufferedReader reader;//
BufferedWriter writer;//
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
initView();
}
private void initView() {
name = getIntent().getStringExtra("name");
socket = MainActivity.socket;
btnSent = (ButtonFlat) findViewById(R.id.btn_sent);
metMsg = (MaterialEditText) findViewById(R.id.met_msg);
lvMsg = (ListView) findViewById(R.id.lv_msg);
adapter = new MessageAdapter(this,msgList);
lvMsg.setAdapter(adapter);
// ,
getMessage();
btnSent.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ChatMessage chatMessage = new ChatMessage();
chatMessage.setType(2);
chatMessage.setName(name);
chatMessage.setMessage(metMsg.getText().toString());
msgList.add(chatMessage);
adapter.notifyDataSetChanged();
String message = name + "," + metMsg.getText().toString();
metMsg.setText("");
setMessage(message);
}
});
}
/**
*
* @param message
*/
private void setMessage(String message) {
try {
if (writer != null) {
writer.write(message + "
");
writer.flush();
} else {
Toast.makeText(ChatActivity.this, " YY !", Toast.LENGTH_LONG).show();
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
*
*/
private void getMessage() {
new Thread(new Runnable() {
@Override
public void run() {
try {
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
ChatMessage chatMessage = new ChatMessage();
String[] temp = line.split(",");
System.out.print(temp[0]);
if(temp[0].equals("system")){// temp[0]=system
chatMessage.setType(0);
chatMessage.setMessage(temp[1]);
}else{
chatMessage.setType(1);
chatMessage.setName(temp[0]);
chatMessage.setMessage(temp[1]);
}
msgList.add(chatMessage);
handler.sendEmptyMessage(0x00);
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
adapter.notifyDataSetChanged();
return false;
}
});
}
に注意
サーバIPの表示
cmdを開いて、ipconfigを入力すると、自機のIP設定が見えます.無線LANでwifiに適しています.ここのIPv 4アドレスはサーバーのIPです.
携帯電話がサーバーに接続できない
シミュレータはサーバーに接続できますが、携帯電話が接続できない場合はどうすればいいですか?ネット上では携帯電話は外網だと言っていますが、内網にアクセスできない問題は、携帯電話とパソコンを1つのwifiと一緒にすればいいです.