Android网络编程之Socket通信

Socket(套接字)是一种通信机制,可以实现单机或跨网络进行通信,其创建需要明确的区分C(客户端)/S(服务器端),支持多个客户端连接到同一个服务器。有两种传输模式:

1)、面向连接的传输:基于TCP协议,可靠性高,但效率低;

2)、面向无连接的传输:基于UDP协议,可靠性低,但效率高;

Android中,直接采用Socket通信应该是我们遇到的最低级的网络运用。尽管已经作了很大程度的抽象,但是纯粹的Socket通信,仍然给开发者留下很多细节需要处理,尤其在服务器端,开发者需要处理多线程以及数据缓冲等的设计问题。相对而言,处于更高抽象层的HTTP等,已经对Socket通信中需要处理的技术细节进行了很好的封装,开发者无须关心,因此,HTTP在网络开发中通常具有决定性的优势。

Android在其核心库的java包中,提供了用于客户端的Socket class和用于服务器端的ServerSocket class,分别位于$SOURCE/libcore/luni/src/main/java/java/net/Socket.java和$SOURCE/libcore/luni/src/main/java/java/net/ServerSocket.java文件中。分析两个class的源码,可以看出封装考虑的很全面,只构造方法一向每个class都考虑了很多种使用情况。由于本人只是初学者,很多理解的不深入,这里只抛砖引玉的对两个class的构造方法分别介绍一种,就是我下面的程序中用到的:

Socket(String dstName, int dstPort):创建一个以流的方式(基于TCP协议)连接到目标机(这里可以理解为服务器)的客户端Socket;dstName是目标机的IP地址,dstPort是要连接的目标机的端  口号。这里要注意对端口的理解,它不能理解为物理上的一个接口,而是对计算机中一块特殊内存区域的形象表述。

ServerSocket(int aport):创建一个绑定到本机指定端口的服务端Socket;aport就是指定的本机端口。与上述客户端Socket对应,通过TCP连接时,ServerSocket创建后需要在aport端口上进行监听,等待客户端的连接。

启动 service 和 activity

mContext.startService(new Intent(mContext, SocketService.class));

Intent intent = new Intent();

intent.setClass(mContext, SocketClientDemo.class);

mContext.startActivity(intent);

service :服务端

package com.android.settings;

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 android.app.Service;

import android.content.Intent;

import android.os.IBinder;

public class SocketService extends Service {

Thread mServiceThread;

Socket client;

@Override

public IBinder onBind(Intent intent) {

// TODO Auto-generated method stub

return null;

}

@Override

public void onCreate() {

// TODO Auto-generated method stub

super.onCreate();

mServiceThread = new Thread(new SocketServerThread());

}

@Override

public void onStart(Intent intent, int startId) {

// TODO Auto-generated method stub

super.onStart(intent, startId);

mServiceThread.start();

}

@Override

public void onDestroy() {

// TODO Auto-generated method stub

super.onDestroy();

}

public class SocketServerThread extends Thread {

private static final int PORT = 54321;

private SocketServerThread() {

}

@Override

public void run() {

try {

ServerSocket server = new ServerSocket(PORT);

while (true) {

System.out.println("tian begin client connected");

client = server.accept();

System.out.println(" tian client connected");

BufferedReader reader = new BufferedReader(

new InputStreamReader(client.getInputStream()));

System.out.println(" tian read from client:");

String textLine = reader.readLine();

if (textLine.equalsIgnoreCase("EXIT")) {

System.out

.println(" tian EXIT invoked, closing client");

break;

}

System.out.println(textLine);

PrintWriter writer = new PrintWriter(new BufferedWriter(

new OutputStreamWriter(client.getOutputStream())));

System.out.println(" return tian read from client:"

+ textLine);

writer.println(" tian ECHO from server: " + textLine);

writer.flush();

writer.close();

reader.close();

}

} catch (IOException e) {

// TODO Auto-generated catch block

System.err.println(e);

}

}

}

}

package com.android.settings;

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 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;

public class SocketClientDemo extends Activity {

private static final String SERVERIP = "127.0.0.1";

private static final int SERVERPORT = 54321;

private static final String TAG = "SocketClientDemo";

TextView mMsgRev;

EditText mMsgEdit;

Button mMsgSendBtn;

String mSendMsg;

String mReceivedMsg;

class MyThread implements Runnable {

private String name;

public MyThread(String name) {

this.name = name;

}

public void run() {

// for (int i = 0; i < 100; i++) {

// System.out.println("线程开始:" + this.name + ",i=" + i);

Log.d(TAG, "MyThread  execu");

// }

}

};

class MyThread2 extends Thread {

@Override

public void run() {

// TODO Auto-generated method stub

Log.d(TAG, "MyThread2  execu");

}

};

class MyThread3 extends Thread {

private String name;

public MyThread3(String name) {

// super();

this.name = name;

}

@Override

public void run() {

// TODO Auto-generated method stub

Log.d(TAG, "MyThread3  execu" + "name=" + name);

Socket socket = null;

mSendMsg = mMsgEdit.getText().toString();

try {

socket = new Socket(SERVERIP, SERVERPORT);

PrintWriter writer = new PrintWriter(new BufferedWriter(

new OutputStreamWriter(socket.getOutputStream())));

writer.println(mSendMsg);

writer.flush();

BufferedReader reader = new BufferedReader(

new InputStreamReader(socket.getInputStream()));

mReceivedMsg = reader.readLine();

Message meaage = mHander.obtainMessage();

meaage.arg1 = 1;

mHander.sendMessage(meaage);

writer.close();

reader.close();

socket.close();

} catch (UnknownHostException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.xml.beidou_detail_preference_settings);

mMsgRev = (TextView) findViewById(R.id.receive_msg);

mMsgEdit = (EditText) findViewById(R.id.edit_msg);

mMsgSendBtn = (Button) findViewById(R.id.send_msg);

mMsgSendBtn.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

/*

* MyThread thread = new MyThread("00"); new

* Thread(thread).start();

*

* new MyThread2().start();

*/

MyThread3 thread3 = new MyThread3("33");

thread3.start();

}

});

}

final Handler mHander = new Handler() {

@Override

public void handleMessage(Message msg) {

// TODO Auto-generated method stub

if (mReceivedMsg != null) {

mMsgRev.setText(mReceivedMsg);

} else {

mMsgRev.setText("tian receive data error");

}

super.handleMessage(msg);

}

};

}

activity : 客户端

package com.android.settings;

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 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;

public class SocketClientDemo extends Activity {

private static final String SERVERIP = "127.0.0.1";

private static final int SERVERPORT = 54321;

private static final String TAG = "SocketClientDemo";

TextView mMsgRev;

EditText mMsgEdit;

Button mMsgSendBtn;

String mSendMsg;

String mReceivedMsg;

class MyThread implements Runnable {

private String name;

public MyThread(String name) {

this.name = name;

}

public void run() {

// for (int i = 0; i < 100; i++) {

// System.out.println("线程开始:" + this.name + ",i=" + i);

Log.d(TAG, "MyThread  execu");

// }

}

};

class MyThread2 extends Thread {

@Override

public void run() {

// TODO Auto-generated method stub

Log.d(TAG, "MyThread2  execu");

}

};

class MyThread3 extends Thread {

private String name;

public MyThread3(String name) {

// super();

this.name = name;

}

@Override

public void run() {

// TODO Auto-generated method stub

Log.d(TAG, "MyThread3  execu" + "name=" + name);

Socket socket = null;

mSendMsg = mMsgEdit.getText().toString();

try {

socket = new Socket(SERVERIP, SERVERPORT);

PrintWriter writer = new PrintWriter(new BufferedWriter(

new OutputStreamWriter(socket.getOutputStream())));

writer.println(mSendMsg);

writer.flush();

BufferedReader reader = new BufferedReader(

new InputStreamReader(socket.getInputStream()));

mReceivedMsg = reader.readLine();

Message meaage = mHander.obtainMessage();

meaage.arg1 = 1;

mHander.sendMessage(meaage);

writer.close();

reader.close();

socket.close();

} catch (UnknownHostException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.xml.beidou_detail_preference_settings);

mMsgRev = (TextView) findViewById(R.id.receive_msg);

mMsgEdit = (EditText) findViewById(R.id.edit_msg);

mMsgSendBtn = (Button) findViewById(R.id.send_msg);

mMsgSendBtn.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

/*

* MyThread thread = new MyThread("00"); new

* Thread(thread).start();

*

* new MyThread2().start();

*/

MyThread3 thread3 = new MyThread3("33");

thread3.start();

}

});

}

final Handler mHander = new Handler() {

@Override

public void handleMessage(Message msg) {

// TODO Auto-generated method stub

if (mReceivedMsg != null) {

mMsgRev.setText(mReceivedMsg);

} else {

mMsgRev.setText("tian receive data error");

}

super.handleMessage(msg);

}

};

}

时间: 2024-10-13 23:23:52

Android网络编程之Socket通信的相关文章

Java网络编程之Socket通信(二)

之前在前面已经介绍了Socket通信的一些基本原理,以及如何让客户端与服务器端建立通信,和实现通信的一些基本步骤(包括首先使得服务器端与客户端建立连接,建立连接之后,服务器端开始侦听客户端的请求,侦听到客户端的请求之后,通过输入输出流处理相关信息实现通信,最后通信完毕结束通信等一系列流程). 但是之前只是单个客户端与服务器进行通信,而我们实际应用中单个客户端的情况几乎不存在,都是多个客户端同时与服务器进行交互(这里同时交互就会出现并发性的问题,对于并发性的问题暂时还不是很懂,只知道有这个概念),

Android网络编程之Http通信

Android中提供的HttpURLConnection和HttpClient接口可以用来开发HTTP程序.以下是本人在学习中的总结与归纳.1. HttpURLConnection接口    首先需要明确的是,Http通信中的POST和GET请求方式的不同.GET可以获得静态页面,也可以把参数放在URL字符串后面,传递给服务器.而POST方法的参数是放在Http请求中.因此,在编程之前,应当首先明确使用的请求方法,然后再根据所使用的方式选择相应的编程方式.    HttpURLConnectio

【转】JAVA网络编程之Socket用法

JAVA网络编程之Socket用法 分类: JAVA2012-08-24 15:56 710人阅读 评论(0) 收藏 举报 在客户/服务器通信模式中,客户端需要主动建立与服务器连接的Socket,服务器端收到客户端的连接请求,也会创建与客户端连接的Socket.Socket可以看做是通信连接两端的收发器,客户端和服务店都通过Socket来收发数据. 1.构造Socket public Socket() 通过系统默认类型的 SocketImpl 创建未连接套接字 public Socket(Str

网络编程之Socket &amp; ServerSocket

网络编程之Socket & ServerSocket Socket:网络套接字,网络插座,建立网络通信连接至少要一对端口号(socket).socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口:socket用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信. 1.客户端Socket类 此类实现客户端套接字 构造方法 构造方法 作用 Socket(String host, i

网络编程之socket

网络编程之socket socket:在网络编程中的一个基本组件,也称套接字. 一个套接字就是socket模块中的socket类的一个实例. 套接字包括两个: 服务器套接字和客户机套接字 套接字的实例化需要3个参数: 1.地址簇:socket.AF_INET 2. 流:socket.SOCK_STREAM 3.使用的协议: 默认为0 服务器套接字:以下简称socket_server 客户端套接字:以下简称socket_client 地址:address=('127.0.0.1',8000) so

android网络编程之pull解析xml

android网络编程之pull解析xml 除了前面介绍过的SAX以及DOM方法,还可以通过Pull对xml文档进行一个解析.Pull解析器的解析方式与SAX非常相似.它提供了类似的事件,使用parser.next()可以进入下一元素并触发相应事件,事件将作为数值代码被发送,因此可以使用一个switch对感兴趣的事件进行选择,然后进行相应的处理,调用parser.nextText()方法可以获取下一个Text类型元素的值. pull解析器特点: *结构简单:一个接口.一个例外.一个工厂就组成了P

网络编程之Socket的TCP协议实现客户端与客户端之间的通信

我认为当你学完某个知识点后,最好是做一个实实在在的小案例.这样才能更好对知识的运用与掌握 如果你看了我前两篇关于socket通信原理的入门文章.我相信对于做出我这个小案列是完全没有问题的!! 既然是小案列.就难免会有很多不足,所以还请大家见谅.先说下用此案例实现的功能 利用Socke的TCP协议实现了 1:端与端之间的通信(客户端和客户端)包括发送文字,小文件,抖动效果 2:同步实现好友下线与上线的效果,即有其他客户端上线会通知其他已经在线的客户端 3:实现自定义通信协议 服务器窗体布局 布局很

【python之路35】网络编程之socket相关

Socket socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. socket起源于Unix,而Unix/Linux基本哲学之一就是"一切皆文件",对于文件用[打开][读写][关闭]模式来操作.socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO.打开.关闭) socket和file的区别: fil

网络编程之socket新解

由于工作并不是很忙,闲暇之余就读了下tomcat的源代码.我是从事java服务器开发工作的,大体的一些服务器线程模型我都是了解的.其大部分都是由一个线程调用监听端口等待客户端的链接,建立连接后再交由其他的线程负责具体的网络io操作.可tomcat居然是用多个线程调用同一个ServerSocket实例的accept方法.我读过mina也读过netty的源码,自己在大学时也写过不少的基于socket通信的程序,但是这种用法自己从未想过也从未见过.(恕本人咕噜寡闻了,-_-|||)不免好奇,这么做原来