Android Socket编程
花了大概两天的时间,终于把Android的Socket编程给整明白了。抽空和大家分享一下:
Socket Programming on Android
Socket 编程基础知识:
主要分服务器端编程和客户端编程。
服务器端编程步骤:
1: 创建服务器端套接字并绑定到一个端口上(0-1023是系统预留的,最好大约1024)
2: 套接字设置监听模式等待连接请求
3: 接受连接请求后进行通信
4: 返回,等待赢一个连接请求
客户端编程步骤:
1: 创建客户端套接字(指定服务器端IP地址与端口号)
2: 连接(Android 创建Socket时会自动连接)
3: 与服务器端进行通信
4: 关闭套接字
Android Socket 通信原理注意:
1: 中间的管道连接是通过InputStream/OutputStream流实现的。
2: 一旦管道建立起来可进行通信
3: 关闭管道的同时意味着关闭Socket
4: 当对同一个Socket创建重复管道时会异常
5: 通信过程中顺序很重要:服务器端首先得到输入流,然后将输入流信息输出到其各个客户端
客户端先建立连接后先写入输出流,然后再获得输入流。不然活有EOFException的异常。
下面是关于在服务器端编程的代码:
- import java.io.DataInputStream;
- import java.io.DataOutputStream;
- import java.io.IOException;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.util.ArrayList;
- /**
- *@author Andrew.Lee
- *@create 2011-6-1 下午04:45:19
- *@version 1.0
- *@see
- */
- public class Server {
- static ServerSocket aServerSocket = null; // Server Socet.
- DataInputStream aDataInput = null; // Server input Stream that to
- // receive msg from client.
- DataOutputStream aDataOutput = null; // Server output Stream that to
- static ArrayList list = new ArrayList();
- public static void main(String[] args) {
- try {
- aServerSocket = new ServerSocket(50003); // listen 8888 port.
- System.out.println("already listen 50003 port.");
- } catch (Exception e) {
- e.printStackTrace();
- }
- int num = 0;
- while (num < 10) {
- Socket aSessionSoket = null;
- try {
- aSessionSoket = aServerSocket.accept();
- MyThread thread = new Server().new MyThread(aSessionSoket);
- thread.start();
- num = list.size();
- } catch (IOException e1) {
- // TODO Auto-generated catch block
- e1.printStackTrace();
- }
- }
- }
- class MyThread extends Thread {
- Socket aSessionSoket = null;
- public MyThread(Socket socket) {
- aSessionSoket = socket;
- }
- public void run() {
- try {
- aDataInput = new DataInputStream(aSessionSoket.getInputStream());
- aDataOutput = new DataOutputStream(aSessionSoket
- .getOutputStream());
- list.add(aDataOutput);
- while (true) {
- String msg = aDataInput.readUTF(); // read msg.
- if (!msg.equals("connect...")) {
- System.out.println("ip: "
- + aSessionSoket.getInetAddress());// ip.
- System.out.println("receive msg: " + msg);
- for (int i = 0; i < list.size(); i++) {
- DataOutputStream output = (DataOutputStream) list
- .get(i);
- output.writeUTF(msg + "----" + list.size());
- }
- if (msg.equals("end"))
- break;
- }
- aDataOutput.writeUTF("");
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } finally {
- try {
- aDataInput.close();
- if (aDataOutput != null)
- aDataOutput.close();
- list.remove(aDataOutput);
- aSessionSoket.close();
- } catch (Exception e2) {
- e2.printStackTrace();
- }
- }
- }
- }
- }
注意问题:为了实现对于多个客户端的处理,使用了多线程的操作,每个线程维护一个Socket的连接与通信,新连接的Socket的管道被加入到ArrayList中。对于输出流的操作是对于所有的连接的客户端进行写数据。对于关闭了Socket的客户端管道从List中移除。
客户端编程代码:
- package com.daisy.android.network;
- import java.io.DataInputStream;
- import java.io.DataOutputStream;
- import java.io.IOException;
- import java.net.InetSocketAddress;
- import java.net.Socket;
- import java.net.SocketAddress;
- import java.net.UnknownHostException;
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.TextView;
- /**
- *@author Andrew.Lee
- *@create 2011-5-28 下午02:26:20
- *@version 1.0
- *@see
- */
- public class SocketActivity extends Activity {
- EditText editText = null;
- Button sendButton = null;
- TextView display = null;
- Socket client = null;
- MyHandler myHandler;
- DataOutputStream dout;
- DataInputStream din;
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.clientsocket);
- editText = (EditText) findViewById(R.id.message);
- sendButton = (Button) findViewById(R.id.send);
- display = (TextView) findViewById(R.id.display);
- sendButton.setOnClickListener(listener);
- try {
- client = new Socket("192.168.0.120", 50003);
- dout = new DataOutputStream(client.getOutputStream());
- din = new DataInputStream(client.getInputStream());
- } catch (UnknownHostException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- myHandler = new MyHandler();
- MyThread m = new MyThread();
- m.start();
- }
- class MyHandler extends Handler {
- public MyHandler() {
- }
- // 子类必须重写此方法,接受数据
- @Override
- public void handleMessage(Message msg) {
- // TODO Auto-generated method stub
- Log.d("MyHandler", "handleMessage......");
- super.handleMessage(msg);
- // 此处可以更新UI
- if (client != null && client.isConnected()) {
- Log.i("handler..", "*-----*");
- try {
- dout.writeUTF("connect...");
- String message = din.readUTF();
- if (!message.equals(""))
- display.setText(display.getText().toString() + "\n"
- + "服务器发来的消息--:" + message);
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }
- class MyThread extends Thread {
- public void run() {
- while (true) {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- Message msg = new Message();
- SocketActivity.this.myHandler.sendMessage(msg);
- }
- }
- }
- OnClickListener listener = new OnClickListener() {
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- String sendText = editText.getText().toString();
- try {
- // din = new DataInputStream(client.getInputStream());
- dout.writeUTF(sendText);
- /*
- * display.setText(display.getText().toString() + "\n" +
- * "服务器发来的消息:" + din.readUTF());
- */
- /*
- * display.setText(display.getText().toString() + "\n" +
- * "服务器发来的消息--:" + din.readUTF());
- */
- } catch (UnknownHostException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- };
- }
注意:为实现对于UI的间歇性刷新操作,使用到了Handler的消息机制。
附注:以上只是对Android的Socket编程的大致思路和过程,其中缺少了对于InputStream/OututStream 的异常处理,连接超时等处理。
摘自:http://duguyidao.iteye.com/blog/1069736
Android Socket编程的更多相关文章
- Android Socket编程学习笔记
http://blog.csdn.net/eyu8874521/article/details/8847173 度娘给出的描述:通常也称作"套接字",用于描述IP地址和端口,是一个 ...
- Android Socket编程基础
前些天写了一个Android手机在局域网内利用Wifi进行文件传输的Demo,其中用到了Socket编程,故此总结(盗了网友的一些图和文字).好久好久没来博客园了~~ 1.什么是Socket? soc ...
- android socket编程用Bufferreader读取的一个失败教训
由于我的手机需要用笔记本开的wifi,躺在床上玩手机时需要关电脑或者是要让电脑放歌的时候总是不想下床,于是我想能不能用一个APP,然后通过局域网实现在手机上对电脑进行操控呢?说干就干. 我在电脑上用的 ...
- android Socket 编程
Socket 通信 1.UDP实现 (DatagramSocket) [客户端] //首先创建一个DatagramSocket对象 DatagramSocket socket = new Datag ...
- Android网络编程系列 一 Socket抽象层
在<Android网络编程>系列文章中,前面已经将Java的通信底层大致的描述了,在我们了解了TCP/IP通信族架构及其原理,接下来我们就开始来了解基于tcp/ip协议层的Socket抽 ...
- Android 网络编程 Socket
1.服务端开发 创建一个Java程序 public class MyServer { // 定义保存所有的Socket,与客户端建立连接得到一个Socket public static List< ...
- android开发系列之socket编程
上周在项目遇到一个接口需求就是通讯系列必须是socket,所以在这篇博客里面我想谈谈自己在socket编程的时候遇到的一些问题. 其实在android里面实现一个socket通讯是非常简单的,我们只需 ...
- Android应用开发提高篇(4)-----Socket编程(多线程、双向通信)
链接地址:http://www.cnblogs.com/lknlfy/archive/2012/03/04/2379628.html 一.概述 关于Socket编程的基本方法在基础篇里已经讲过,今天把 ...
- 基于libevent, libuv和android Looper不断演进socket编程 - 走向架构师之路 - 博客频道 - CSDN.NET
基于libevent, libuv和android Looper不断演进socket编程 - 走向架构师之路 - 博客频道 - CSDN.NET 基于libevent, libuv和android L ...
随机推荐
- 安装 SPRING TOOL SUITE
- centos 安装 谷歌BBR
使用root用户登录,运行以下命令: wget --no-check-certificate https://github.com/teddysun/across/raw/master/bbr.sh ...
- MySQL 触发器简单实例 - 转载
MySQL 触发器简单实例 触发器:可以更新,删除,插入触发器,不同种类的触发器可以存在于同一个表,但同种类的不能有多个.一个更新.一个删除是可以共存的. ~~语法~~ CREATE TRIGGER ...
- 摘录:Jetty 的工作原理以及与 Tomcat 的比较
引子:Jetty 应该是目前最活跃也是很有前景的一个 Servlet 引擎.本文将介绍 Jetty 基本架构与基本的工作原理:您将了解到 Jetty 的基本体系结构:Jetty 的启动过程:Jetty ...
- Pandas统计函数
统计方法有助于理解和分析数据的行为.现在我们将学习一些统计函数,可以将这些函数应用到Pandas的对象上. pct_change()函数 系列,DatFrames和Panel都有pct_change( ...
- Kubernetes的网络模型
http://blog.csdn.net/zjysource/article/details/52052420
- yii2:redis调用
参照手册,调用redis,报错,真坑: Yii::$app->redis 后改改用: Yii::getRedis();
- 四十 Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)倒排索引
倒排索引 倒排索引源于实际应用中需要根据属性的值来查找记录.这种索引表中的每一项都包括一个属性值和具有该属性值的各记录的地址.由于不是由记录来确定属性值,而是由属性值来确定记录的位置,因而称为倒排索引 ...
- 亲测安装nginx1.8.1 日期2016年3月16日
1.安装nginx tar zxvf nginx-1.8.1.tar.gz cd nginx-1.8.1 ./configure make make install /usr/local/nginx/ ...
- oracle数据库查看用户相关语句
1.查看所有用户: select * from dba_users; select * from all_users; select * from user_users; 2.查看用户 ...