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连接使用的是“请求—响应方式”,即在请求时建立连接通道,当客 ...
随机推荐
- 通过jquery 获取文本框的聚焦和失焦方法
我还是喜欢用jquery来实现,不管页面中多少个输入框需要实现聚焦,失焦,都公有,我常用的方法是: 遍历该页面中的input框,获取输入框中的val值,当该输入框聚焦的时候跟存放的oldValue值进 ...
- 编程作业—C++初探 简单的学生信息处理程序实现
简单的学生信息处理程序实现 来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩.) 注意: 总时间限制: 1000ms 内存限制: 65536kB 描述 ...
- [leetcode]_Unique Paths
题目:有一个m * n 的方格,如下图,一个小robot希望从左上角走到右下角,共有多少种不同的路线走法. 思路: 我的错误思路:全排列,从(0,0)走到(m - 1,n - 1)共需要往下走m-1步 ...
- HTML5 对于手机页面长按会粘贴复制的禁用 (解决方案)
解决方案: 直接在CSS 文件中添加下面的代码,就可以实现了在手机端禁止粘贴复制的功能: *{ -webkit-touch-callout:none; /*系统默认菜单被禁用*/ -we ...
- MinGW编译wxWidgets中的问题及解决方法
其实网上wxWidgets编译相关的博文,都没写到关键点上,泛泛而谈——就写了执行几个命令,就万事大吉了! 维基百科上的这个页面讲解了编译中可能遇到的各种问题及解决办法.比较懒,不想翻译.wxWidg ...
- 如何在Netbeans中查看TODO项
以下要说的内容可能不起眼,但本人在找的时候着实费了一番功夫,个人感觉网上说的不着点,就在这儿有针对性地记录下来操作流程吧. 关于TODO的作用这里不做说明,在IDE中编写代码时,我们总会用到TODO, ...
- JavaService应用中的注意事项
最近有个技术需求,要把已写好的Java程序注册成Windows服务,网上搜了两个快捷办法,一个是Java Service Wrapper,这是个收费的第三方组件,免费的版本还没有适合64位Win7系统 ...
- javascript回车完美实现tab切换功能
javascript通过回车实现tab切换功能,最经有一个项目是给化工厂做的在使用的过程中需要输入大量的数据,使用的都是小键盘区,在以前都是通过excel录入数据的现在, 在网页上需要实现excel ...
- Java求和
用while结构求0~100的整数数字之和. 代码如下: public class WhileDemo { public static void main(String[] args) { int l ...
- AngularJs记录学习04
<html> <head> <title>Angular JS Views</title> <script src="js/Angula ...