Android 客户端通过服务器进行多客户端通信
程序员文章站
2024-03-23 10:10:10
...
android 客户端向服务器发送信息,服务器接收信息并转发给另外一个客户端,实现简单群聊功能
网络权限:<uses-permission android:name="android.permission.INTERNET" />
服务器端源码:
package server;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class server {
// 定义相关的参数,端口,存储Socket连接的集合,ServerSocket对象
// 以及线程池
private static final int PORT = 9090;//定义端口
private List<Socket> mList = new ArrayList<Socket>();
private ServerSocket server = null;
private ExecutorService myExecutorService = null;
public static void main(String[] args) {
new server();
}
public server() {
try {
server = new ServerSocket(PORT);
// 创建线程池
myExecutorService = Executors.newCachedThreadPool();
System.out.println("服务端已运行...\n");
Socket client = null;
while (true) {
client = server.accept();
mList.add(client);
myExecutorService.execute(new Service(client));
}
} catch (Exception e) {
e.printStackTrace();
}
}
class Service implements Runnable {
private Socket socket;
private BufferedReader in = null;
private String msg =null;
public Service(Socket socket) {
this.socket = socket;
try {
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
msg = "用户:" + this.socket.getInetAddress() + "~加入了聊天室," + "当前在线人数:" + mList.size();
this.sendmsg();
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
try {
while (true) {
if ((msg = in.readLine()) != null) {
if (msg.equals("bye")) {
System.out.println("-------------------");
mList.remove(socket);
in.close();
msg = "用户:" + socket.getInetAddress() + "退出:" + "当前在线人数:" + mList.size();
socket.close();
this.sendmsg();
break;
} else {
msg = socket.getInetAddress() + " 说: " + msg;
this.sendmsg();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 为连接上服务端的每个客户端发送信息
public void sendmsg() {
System.out.println(msg);
int num = mList.size();
for (int index = 0; index < num; index++) {
Socket mSocket = mList.get(index);
PrintWriter pout = null;
try {
pout = new PrintWriter(
new BufferedWriter(new OutputStreamWriter(mSocket.getOutputStream(), "UTF-8")), true);
pout.println(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
客户端源码:
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="聊天室" />
<EditText
android:id="@+id/editsend"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btnsend"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="发送" />
<ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint=""
/>
</ScrollView>
</LinearLayout>
MainActivity
package com.example.client;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
// 定义相关变量,完成初始化
private TextView textView;
private EditText editsend;
private Button btnsend;
private static final String HOST = "10.32.157.135";
private static final int PORT = 9090;
private Socket socket = null;
private BufferedReader in = null;
private PrintWriter out = null;
private String content = "";
private StringBuilder sb = null;
// 定义一个handler对象,用来刷新界面
@SuppressLint("HandlerLeak")
public Handler handler = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == 0x123) {
//Bundle bundle = msg.getData();
sb.append(content);
textView.setText(sb.toString());
editsend.setText("");
//textView.append("server:" + bundle.getString("msg") + "\n");
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sb = new StringBuilder();
textView = (TextView) findViewById(R.id.textView);
editsend = (EditText) findViewById(R.id.editsend);
btnsend = (Button) findViewById(R.id.btnsend);
// 当程序一开始运行的时候就实例化Socket对象,与服务端进行连接,获取输入输出流
// 因为4.0以后不能再主线程中进行网络操作,所以需要另外开辟一个线程
new Thread() {
public void run() {
try {
socket = new Socket(HOST, PORT);
in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
// 为发送按钮设置点击事件
btnsend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String msg = editsend.getText().toString().trim();
if (socket.isConnected()) {
if (!socket.isOutputShutdown()) {
out.println(msg);
//if (TextUtils.isEmpty(msg)) {
// Toast.makeText(MainActivity.this, "内容不能为空", 1).show();
//}
}
//textView.append("client:" + textView.toString() + "\n");
textView.setText("");
}
}
});
new Thread() {
@Override
public void run() {
try {
while (true) {
if (socket.isConnected()) {
if (!socket.isInputShutdown()) {
if ((content = in.readLine()) != null) {
content += "\n";
handler.sendEmptyMessage(0x123);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
上一篇: 宏函数、Makefile
下一篇: Android 之生成图形验证码
推荐阅读
-
Android 客户端通过服务器进行多客户端通信
-
android客户端与javaweb服务器端数据通信-异步Get
-
android客户端与javaweb服务器端数据通信-Post-键值对
-
Android实现蓝牙客户端与服务器端通信示例
-
Android实现蓝牙客户端与服务器端通信示例
-
面向UDP的Android——PC双向通信(三):在Android客户端和PC服务器端之间传输自定义对象
-
php做的服务器端,客户端用android手机,通信问题
-
python服务器与android客户端socket通信实例
-
学习笔记--Android TCP客户端与服务器端不能通信之一
-
Android编程之客户端通过socket与服务器通信的方法