12、android socket使用demo:网络聊天
目录:
一、效果图
二、原代码分享
三、代码分析
四、总结
一、效果图如下:
客户端1: 客户端2:
二、原代码分享如下:
1、java代码只有一个
MainActivity.java
1 package com; 2 3 import java.io.BufferedReader; 4 import java.io.IOException; 5 import java.io.InputStreamReader; 6 import java.io.OutputStream; 7 import java.io.UnsupportedEncodingException; 8 import java.net.ServerSocket; 9 import java.net.Socket; 10 import java.util.ArrayList; 11 12 import android.app.Activity; 13 import android.os.Bundle; 14 import android.os.Handler; 15 import android.os.Message; 16 import android.view.View; 17 import android.view.View.OnClickListener; 18 import android.widget.Button; 19 import android.widget.CheckBox; 20 import android.widget.CompoundButton; 21 import android.widget.CompoundButton.OnCheckedChangeListener; 22 import android.widget.EditText; 23 import android.widget.TextView; 24 25 import com.example.androidsockettest.R; 26 27 public class MainActivity extends Activity{ 28 29 private Button button_send = null; 30 private EditText et_ip = null; 31 private EditText et_port = null; 32 private EditText et_conent = null; 33 private TextView tv_history = null; 34 private CheckBox checkBoxSwitch = null; 35 private static int defaultPort = 8888; 36 public static ArrayList<Socket> socketList=new ArrayList<Socket>(); 37 38 private OutputStream out=null; 39 private Handler handler = null; 40 private Socket s = null; 41 String tag = "chatRoom"; 42 private BufferedReader buRead = null; 43 44 private final int UPDATE_HISTORY_CONTENT = 0; 45 private final int UPDATE_INPUT_CONTENT = 1; 46 47 @Override 48 protected void onCreate(Bundle savedInstanceState) { 49 // TODO Auto-generated method stub 50 super.onCreate(savedInstanceState); 51 setContentView(R.layout.main_activity); 52 53 init(); 54 55 configure(); 56 57 serverStart(); 58 } 59 60 @Override 61 protected void onDestroy() { 62 // TODO Auto-generated method stub 63 super.onDestroy(); 64 } 65 66 67 public void init() 68 { 69 button_send = (Button)findViewById(R.id.button_send); 70 et_ip = (EditText)findViewById(R.id.editText_ip); 71 et_port = (EditText)findViewById(R.id.EditText_port); 72 et_conent = (EditText)findViewById(R.id.EditText_content); 73 tv_history = (TextView)findViewById(R.id.textView_history_content); 74 checkBoxSwitch = (CheckBox)findViewById(R.id.checkBox_server_start); 75 } 76 77 78 public void configure() 79 { 80 button_send.setOnClickListener(new OnClickListener() { 81 82 @Override 83 public void onClick(View v) { 84 // TODO Auto-generated method stub 85 try { 86 String content = et_conent.getText().toString();//读取用户输入文本 87 88 if(out == null) 89 { 90 CommonUtils.LogWuwei(tag,"the fucking out is null"); 91 return; 92 } 93 94 out.write((content+"\n").getBytes("utf-8"));//写入socket 95 96 String history_content = tv_history.getText().toString(); 97 history_content+="你说:"+et_conent.getText()+"\n"; 98 99 100 Message msg = new Message();101 msg.what = UPDATE_HISTORY_CONTENT;102 msg.obj = history_content;103 handler.sendMessage(msg);104 105 msg = new Message();106 msg.what = UPDATE_INPUT_CONTENT;107 msg.obj = "";108 handler.sendMessage(msg);109 110 111 CommonUtils.LogWuwei(tag, "send success");112 } catch (UnsupportedEncodingException e) {113 // TODO Auto-generated catch block114 e.printStackTrace();115 CommonUtils.LogWuwei(tag, "send failed "+e.getMessage());116 } catch (IOException e) {117 // TODO Auto-generated catch block118 e.printStackTrace();119 CommonUtils.LogWuwei(tag, "send failed "+e.getMessage());120 }121 }122 });123 124 125 checkBoxSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() {126 127 @Override128 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {129 // TODO Auto-generated method stub130 if(isChecked)131 {132 CommonUtils.LogWuwei(tag, "clientStart");133 clientStart();134 }135 else136 {137 CommonUtils.LogWuwei(tag, "clientStop");138 clientStop();139 }140 }141 });142 143 144 handler = new Handler()145 {146 @Override147 public void handleMessage(Message msg) {148 // TODO Auto-generated method stub149 super.handleMessage(msg);150 switch (msg.what)151 {152 case UPDATE_HISTORY_CONTENT:153 CommonUtils.LogWuwei(tag, "更新历史记录"+msg.obj);154 tv_history.setText((String)msg.obj);155 break;156 157 case UPDATE_INPUT_CONTENT:158 CommonUtils.LogWuwei(tag, "清空输入记录");159 et_conent.setText("");//清空文本160 break;161 }162 }163 };164 165 }166 167 168 public void serverStart()169 {170 try {171 172 final ServerSocket ss = new ServerSocket(defaultPort);173 174 CommonUtils.LogWuwei(tag, "on serverStart");175 176 new Thread()177 {178 public void run()179 {180 while(true)181 {182 try {183 CommonUtils.LogWuwei(tag, "on serverStart: ready to accept");184 s=ss.accept();185 socketList.add(s);186 buRead = new BufferedReader(new InputStreamReader(s.getInputStream(), "utf-8"));187 188 String receive_content = null;189 while ((receive_content=readFromClient())!=null) {190 CommonUtils.LogWuwei(tag,"客户端说:"+receive_content);191 192 String history_content = tv_history.getText().toString();193 history_content+=s.getInetAddress()+"说:"+receive_content+"\n";194 195 Message msg = new Message();196 msg.what = UPDATE_HISTORY_CONTENT;197 msg.obj = history_content;198 handler.sendMessage(msg);199 200 201 for (Socket ss:socketList) 202 {203 OutputStream out=ss.getOutputStream();204 out.write(("[服务器已经收到消息]"+"\n").getBytes("utf-8"));205 }206 }207 208 209 } catch (UnsupportedEncodingException e) {210 // TODO Auto-generated catch block211 e.printStackTrace();212 } catch (IOException e) {213 // TODO Auto-generated catch block214 e.printStackTrace();215 }216 217 }218 }219 }.start();220 221 } catch (IOException e) {222 // TODO Auto-generated catch block223 e.printStackTrace();224 }225 226 }227 228 229 private String readFromClient(){230 try {231 return buRead.readLine();232 } catch (Exception e) {233 //删除此Socket234 socketList.remove(s);235 }236 return null;237 }238 239 240 public void clientStart()241 {242 new Thread(new Runnable() {243 244 @Override245 public void run() {246 try {247 String ip = et_ip.getText().toString();248 String port = et_port.getText().toString();249 250 if(!port.equals("") && port != null)251 {252 s=new Socket(ip, defaultPort); 253 }254 else255 {256 s=new Socket(ip, Integer.parseInt(port));257 }258 259 out=s.getOutputStream();260 CommonUtils.LogWuwei(tag, "clientStart success");261 262 } catch (IOException e) {263 e.printStackTrace();264 CommonUtils.LogWuwei(tag, "clientStart failed "+e.getMessage());265 }266 }267 }).start();268 269 270 }271 272 273 public void clientStop()274 {275 try {276 if(s != null)277 s.close();278 if(out != null)279 out.close();280 281 } catch (IOException e) {282 // TODO Auto-generated catch block283 e.printStackTrace();284 }285 286 287 }288 289 }View Code
2、xml文件也是只有一个
main_activity.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" > 5 6 <EditText 7 android:id="@+id/editText_ip" 8 android:layout_width="wrap_content" 9 android:layout_height="wrap_content"10 android:layout_toRightOf="@+id/TextView_ip_tips"11 android:layout_marginRight="15dp"12 android:text="192.168.1.232"13 android:ems="10"/>14 15 <TextView16 android:id="@+id/TextView_ip_tips"17 android:layout_width="wrap_content"18 android:layout_height="wrap_content"19 android:layout_alignParentLeft="true"20 android:layout_marginTop="16dp"21 android:text="接受IP:" />22 23 <EditText24 android:id="@+id/EditText_port"25 android:layout_width="wrap_content"26 android:layout_height="wrap_content"27 android:layout_toRightOf="@+id/textView_port_tips"28 android:layout_below="@+id/editText_ip"29 android:layout_marginTop="16dp"30 android:ems="10"31 android:text="8888"32 android:inputType="number" >33 34 <requestFocus />35 </EditText>36 37 <TextView38 android:id="@+id/textView_port_tips"39 android:layout_width="wrap_content"40 android:layout_height="wrap_content"41 android:layout_alignBottom="@+id/EditText_port"42 android:layout_alignParentLeft="true"43 android:text="输入端口号:" />44 45 <TextView46 android:id="@+id/textView_history_content"47 android:layout_width="match_parent"48 android:layout_height="350dp"49 android:layout_below="@+id/checkBox_server_start" /> 50 51 52 53 <Button54 android:id="@+id/button_send"55 android:layout_width="wrap_content"56 android:layout_height="wrap_content"57 android:layout_toRightOf="@+id/EditText_content"58 android:layout_alignParentBottom="true"59 android:text="发送" />60 61 <EditText62 android:id="@+id/EditText_content"63 android:layout_width="wrap_content"64 android:layout_height="wrap_content"65 android:layout_alignParentLeft="true"66 android:layout_alignParentBottom="true"67 android:ems="10" />68 69 <CheckBox70 android:id="@+id/checkBox_server_start"71 android:layout_width="wrap_content"72 android:layout_height="wrap_content"73 android:layout_alignParentLeft="true"74 android:layout_below="@+id/EditText_port"75 android:layout_marginLeft="24dp"76 android:checked="false"77 android:text="开启发送模式" />78 79 </RelativeLayout>View Code
三、代码分析
流程分析:
1、服务端
程序开启的时候,执行serverStart()方法,将自身做为serverSocket,端口号为8888,做为socket的服务器跑起来;
在循环中,通过带有阻塞特性的accept函数等待连接,如果有连接,通过accept函数得到套接字s,然后通过s的getInputStream()方法得到输入流(也就是对方发送的内容),同事也从s的getInetAddress方法得到对方的ip地址;这样一来就读到了两个重要信息 ① ip地址 ②发送过来的内容
2、客户端
在通过设置edittext内容,配置得到对方的IP地址和端口号,如果选中"开启发送模式",然后创建套件字s,通过套接字的getOutputStream()方法得到可写流out;
“发送”按钮的回调函数是用来通过可写流-写入-套接字(写入内容为用户输入的文本)
这样一来,程序基本ok了,然后运行在两部手机上,即可实现基于socket的网络聊天。
四、总结
参考连接:
1、 http://mobile.51cto.com/android-386691.htm
2、http://blog.csdn.net/conowen/article/details/7313671
3、http://www.cnblogs.com/harrisonpc/archive/2011/03/31/2001565.html
socket简单通信的几个关键点:
1、如果要实现接受消息功能,需要本身做为服务端跑起来,同时得到可读流。关键点:serverSocket、getIputStream
2、如果要实现消息发送功能,需要本身创建套接字,并得到可写流,同时设置要发送到的ip和端口号。关键点:socket、getOutputStream、对方IP、对方Port
That's All
没找到在随笔里如何添加附件,工程附件大家去网盘下载去吧。http://pan.baidu.com/s/1o6vA8sU
更多相关文章
- Nginx系列教程(二)| 一文带你读懂Nginx的正向与反向代理
- RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
- 如何在Android平台上使用JS直接调用Java方法
- android canvas与图层的关系
- Android(安卓)RectF转换为Rect的方法
- Android(安卓)Stomp客户端
- android eclipse中导入framework.jar以及使用其隐藏类的方法
- Android中ImageButton自定义按钮的按下效果的代码实现方法,附网上
- Android(安卓)SQLite3 数据库操作