12、android socket使用demo:网络聊天
目录:
一、效果图
二、原代码分享
三、代码分析
四、总结
一、效果图如下:
客户端1: 客户端2:

二、原代码分享如下:
1、java代码只有一个
MainActivity.java
package com; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList; import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.TextView; import com.example.androidsockettest.R; public class MainActivity extends Activity{ private Button button_send = null;
private EditText et_ip = null;
private EditText et_port = null;
private EditText et_conent = null;
private TextView tv_history = null;
private CheckBox checkBoxSwitch = null;
private static int defaultPort = 8888;
public static ArrayList<Socket> socketList=new ArrayList<Socket>(); private OutputStream out=null;
private Handler handler = null;
private Socket s = null;
String tag = "chatRoom";
private BufferedReader buRead = null; private final int UPDATE_HISTORY_CONTENT = 0;
private final int UPDATE_INPUT_CONTENT = 1; @Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity); init(); configure(); serverStart();
} @Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
} public void init()
{
button_send = (Button)findViewById(R.id.button_send);
et_ip = (EditText)findViewById(R.id.editText_ip);
et_port = (EditText)findViewById(R.id.EditText_port);
et_conent = (EditText)findViewById(R.id.EditText_content);
tv_history = (TextView)findViewById(R.id.textView_history_content);
checkBoxSwitch = (CheckBox)findViewById(R.id.checkBox_server_start);
} public void configure()
{
button_send.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
// TODO Auto-generated method stub
try {
String content = et_conent.getText().toString();//读取用户输入文本 if(out == null)
{
CommonUtils.LogWuwei(tag,"the fucking out is null");
return;
} out.write((content+"\n").getBytes("utf-8"));//写入socket String history_content = tv_history.getText().toString();
history_content+="你说:"+et_conent.getText()+"\n"; Message msg = new Message();
msg.what = UPDATE_HISTORY_CONTENT;
msg.obj = history_content;
handler.sendMessage(msg); msg = new Message();
msg.what = UPDATE_INPUT_CONTENT;
msg.obj = "";
handler.sendMessage(msg); CommonUtils.LogWuwei(tag, "send success");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
CommonUtils.LogWuwei(tag, "send failed "+e.getMessage());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
CommonUtils.LogWuwei(tag, "send failed "+e.getMessage());
}
}
}); checkBoxSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
if(isChecked)
{
CommonUtils.LogWuwei(tag, "clientStart");
clientStart();
}
else
{
CommonUtils.LogWuwei(tag, "clientStop");
clientStop();
}
}
}); handler = new Handler()
{
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
switch (msg.what)
{
case UPDATE_HISTORY_CONTENT:
CommonUtils.LogWuwei(tag, "更新历史记录"+msg.obj);
tv_history.setText((String)msg.obj);
break; case UPDATE_INPUT_CONTENT:
CommonUtils.LogWuwei(tag, "清空输入记录");
et_conent.setText("");//清空文本
break;
}
}
}; } public void serverStart()
{
try { final ServerSocket ss = new ServerSocket(defaultPort); CommonUtils.LogWuwei(tag, "on serverStart"); new Thread()
{
public void run()
{
while(true)
{
try {
CommonUtils.LogWuwei(tag, "on serverStart: ready to accept");
s=ss.accept();
socketList.add(s);
buRead = new BufferedReader(new InputStreamReader(s.getInputStream(), "utf-8")); String receive_content = null;
while ((receive_content=readFromClient())!=null) {
CommonUtils.LogWuwei(tag,"客户端说:"+receive_content); String history_content = tv_history.getText().toString();
history_content+=s.getInetAddress()+"说:"+receive_content+"\n"; Message msg = new Message();
msg.what = UPDATE_HISTORY_CONTENT;
msg.obj = history_content;
handler.sendMessage(msg); for (Socket ss:socketList)
{
OutputStream out=ss.getOutputStream();
out.write(("[服务器已经收到消息]"+"\n").getBytes("utf-8"));
}
} } catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}
}.start(); } catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } private String readFromClient(){
try {
return buRead.readLine();
} catch (Exception e) {
//删除此Socket
socketList.remove(s);
}
return null;
} public void clientStart()
{
new Thread(new Runnable() { @Override
public void run() {
try {
String ip = et_ip.getText().toString();
String port = et_port.getText().toString(); if(!port.equals("") && port != null)
{
s=new Socket(ip, defaultPort);
}
else
{
s=new Socket(ip, Integer.parseInt(port));
} out=s.getOutputStream();
CommonUtils.LogWuwei(tag, "clientStart success"); } catch (IOException e) {
e.printStackTrace();
CommonUtils.LogWuwei(tag, "clientStart failed "+e.getMessage());
}
}
}).start(); } public void clientStop()
{
try {
if(s != null)
s.close();
if(out != null)
out.close(); } catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } }
2、xml文件也是只有一个
main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" > <EditText
android:id="@+id/editText_ip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/TextView_ip_tips"
android:layout_marginRight="15dp"
android:text="192.168.1.232"
android:ems="10"/> <TextView
android:id="@+id/TextView_ip_tips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginTop="16dp"
android:text="接受IP:" /> <EditText
android:id="@+id/EditText_port"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/textView_port_tips"
android:layout_below="@+id/editText_ip"
android:layout_marginTop="16dp"
android:ems="10"
android:text="8888"
android:inputType="number" > <requestFocus />
</EditText> <TextView
android:id="@+id/textView_port_tips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/EditText_port"
android:layout_alignParentLeft="true"
android:text="输入端口号:" /> <TextView
android:id="@+id/textView_history_content"
android:layout_width="match_parent"
android:layout_height="350dp"
android:layout_below="@+id/checkBox_server_start" /> <Button
android:id="@+id/button_send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/EditText_content"
android:layout_alignParentBottom="true"
android:text="发送" /> <EditText
android:id="@+id/EditText_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:ems="10" /> <CheckBox
android:id="@+id/checkBox_server_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/EditText_port"
android:layout_marginLeft="24dp"
android:checked="false"
android:text="开启发送模式" /> </RelativeLayout>
三、代码分析
流程分析:
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
12、android socket使用demo:网络聊天的更多相关文章
- 使用socket搭建一个网络聊天室
#服务器端import socket import threading #创建一个TCP端 sock = socket.socket(socket.AF_INET, socket.SOCK_STREA ...
- Android应用开发基础篇(12)-----Socket通信
链接地址:http://www.cnblogs.com/lknlfy/archive/2012/03/03/2378669.html 一.概述 网络通信无论在手机还是其他设备上都应用得非常广泛,因此掌 ...
- Android应用开发基础篇(12)-----Socket通信(转载)
转自:http://www.devdiv.com/android_socket_-blog-258060-10594.html 一.概述 网络通信无论在手机还是其他设备上都应用得非常广泛,因此掌握网络 ...
- Java实现网络聊天中使用的socket API与Linux socket API之间的关系
尝试着用Java编写一个网络聊天程序,发现总不如网上写的好,所以就直接引用了网上大神的优秀代码.代码如下: package project1; import java.awt.*; import ja ...
- 基于Android Classic Bluetooth的蓝牙聊天软件
代码地址如下:http://www.demodashi.com/demo/12133.html BluetoothChat 基于Android Classic Bluetooth的蓝牙聊天软件,目前仅 ...
- Android - 传统蓝牙通信聊天
Android -传统蓝牙通信聊天 技术:java+Android4.4+jdk1.8 运行环境:Android4.4.Android7.0 概述 Android 传统蓝牙的使用,包括开关蓝牙.搜索设 ...
- Netty网络聊天(一) 聊天室实战
首发地址; Netty网络聊天(一) 聊天室实战 之前做过一个IM的项目,里面涉及了基本的聊天功能,所以注意这系列的文章不是练习,不含基础和逐步学习的部分,直接开始实战和思想引导,基础部分需要额外的去 ...
- Android Socket
Android Socket 参考资料 菜鸟教程 怎么理解TCP的面向连接和UDP的无连接 https://www.cnblogs.com/xiaomayizoe/p/5258754.html htt ...
- Android Socket通信详解
一.Socket通信简介 Android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信.两者的最大差异在于,http连接使用的是“请求—响应方式”,即在请求时建立连接通道,当客 ...
随机推荐
- Xen、Openvz、KVM有什么区别?
VPS的全称为Virtual Private Server,叫做虚拟专用服务器(Godaddy称之为Virtual Dedicated Server,VDS).就是利用各种虚拟化手段把单台物理服务器虚 ...
- Spark基础排序+二次排序(java+scala)
1.基础排序算法 sc.textFile()).reduceByKey(_+_,).map(pair=>(pair._2,pair._1)).sortByKey(false).map(pair= ...
- Apache 多端口多站点配置实例
分享下Apache多端口多站点的配置方法,配置apache服务器的朋友参考下. 配置httpd.conf 监听多个端口 复制代码代码如下: # Listen: Allows you to bind A ...
- thinkphp 字段静态验证$_validate中错误提醒多语言化写成{%LANGUATE}的原因
class UserModel extends Model{ protected $_validate = array( array('account', 'require', '{%LANGUAG ...
- 自定义获取html元素对象的7种方法。
- 第二十二章 数据访问(In .net4.5) 之 集合
1. 概述 本章内容包括 .net平台中的集合.如何选择集合 以及 如何实现自定义集合. 2. 主要内容 2.1 使用数组(Array) ]; ; x < arrayOfInt.Length; ...
- Linux内核学习笔记——内核内存管理方式
一 页 内核把物理页作为内存管理的基本单位:内存管理单元(MMU)把虚拟地址转换为物理 地址,通常以页为单位进行处理.MMU以页大小为单位来管理系统中的也表. 32位系统:页大小4KB 64位系统:页 ...
- MySql 用户 及权限操作
bin/msyql -h host -u user -p bin/mysql -u mysql -p 本地登录 如无密码按回车直接进入mySql bin/mysqladmin -u roo ...
- java下的redis操作
Java操作redis(增删改查) Java代码 package sgh.main.powersite; import java.util.ArrayList; import java.util.Ha ...
- squid基础配置
1 2 3 4 5 6 7 8 9 10 vim /etc/squid/squid.conf http_port 192.168.1.12:3128 (可写多个) cache_mem 64MB ...