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端口上进行监听,等待客户端的连接。
上面所写都是些背景知识,下面对本人的编程实践进行详细说明。
1、功能描述
1)、简单的基于Socket的数据通信;
2)、采用TCP方式连接;
3)、采用C/S结构,但服务端只支持一个连接;
4)、客户端能够向服务端发送数据,并显示服务端的返回信息;
5)、服务端能够接收客户端的数据,并将收到的数据以特定的方式返回给客户端;
2、程序实现思路
1)、服务端:设计为在后台执行的service,用一个独立的线程来处理客户端的连接请求、数据接收和返回。为了启动该service,编写个简单的Activity。
2)、客户端:设计为一个Activity,界面由三部分组成:显示服务端返回信息的文本区域(一个文本框);进行数据输入的编辑区域(一个编辑框);以及触发连接请求并执行数据发送的触发区域(一个按钮)。
3、服务端源程序
1)、Activity文件SocketServerDemo.java
- package com.android.sample.SocketServerDemo;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- public class SocketServerDemo extends Activity{
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- System.out.println("begin start service");
- this.startService(new Intent(this, SocketService.class));
- }
- @Override
- protected void onDestroy() {
- // TODO Auto-generated method stub
- super.onDestroy();
- this.stopService(new Intent(this, SocketService.class));
- }
- }
2)、service文件SocketService.java
- package com.android.sample.SocketServerDemo;
- 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("begin client connected");
- client = server.accept();
- System.out.println("client connected");
- BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
- System.out.println("read from client:");
- String textLine = reader.readLine();
- if(textLine.equalsIgnoreCase("EXIT")){
- System.out.println("EXIT invoked, closing client");
- break;
- }
- System.out.println(textLine);
- PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(client.getOutputStream())));
- writer.println("ECHO from server: " + textLine);
- writer.flush();
- writer.close();
- reader.close();
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- System.err.println(e);
- }
- }
- }
- }
3)、AndroidManifest.xml文件,因为需要在其中添加service和网络访问权限,这里一并贴出
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.sample.SocketServerDemo"
- android:versionCode="1"
- android:versionName="1.0">
- <uses-sdk android:minSdkVersion="9" />
- <application android:icon="@drawable/icon" android:label="@string/app_name">
- <activity android:name=".ScreenCastServer"
- android:label="@string/app_name">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- <service android:name="com.android.sample.SocketServerDemo.SocketService">
- </service>
- </application>
- <uses-permission android:name="android.permission.INTERNET"/>
- </manifest>
4、客户端程序
1)、布局文件main.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <TextView
- android:id="@+id/receive_msg"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- />
- <EditText
- android:id="@+id/edit_msg"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- />
- <Button
- android:id="@+id/send_msg"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="send"
- />
- </LinearLayout>
2)、Activity文件SocketClientDemo.java
- package com.android.sample.SocketClientDemo;
- 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.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 = "192.168.1.68";
- private static final int SERVERPORT = 54321;
- TextView mMsgRev;
- EditText mMsgEdit;
- Button mMsgSendBtn;
- String mSendMsg;
- String mReceivedMsg;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- 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) {
- 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();
- if(mReceivedMsg != null){
- mMsgRev.setText(mReceivedMsg);
- }else{
- mMsgRev.setText("receive data error");
- }
- 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();
- }
- }
- });
- }
- }
3)、在AndroidManifest.xml中向服务器端的该文件一样,添加网络访问权限:<uses-permission android:name="android.permission.INTERNET"/>
5、执行环境搭建
服务端程序在开发板上执行,客户端程序在模拟器上执行,实现了基于Socket的数据收发。但是我这里只是进行了局域网内的通信,至于跨网络能不能行,目前条件不够,没法进行验证。
转:http://blog.csdn.net/harry_helei/article/details/6638876
Android网络编程之Socket的更多相关文章
- 网络编程之socket
网络编程之socket socket:在网络编程中的一个基本组件,也称套接字. 一个套接字就是socket模块中的socket类的一个实例. 套接字包括两个: 服务器套接字和客户机套接字 套接字的实例 ...
- 网络编程之Socket & ServerSocket
网络编程之Socket & ServerSocket Socket:网络套接字,网络插座,建立网络通信连接至少要一对端口号(socket).socket本质是编程接口(API),对TCP/IP ...
- GO语言的进阶之路-网络编程之socket
GO语言的进阶之路-网络编程之socket 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是socket; 在说socket之前,我们要对两个概念要有所了解,就是IP和端口 ...
- [深入浅出Cocoa]iOS网络编程之Socket
http://blog.csdn.net/kesalin/article/details/8798039 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] [深入浅出Co ...
- Android网络编程之HttpClient运用
Android网络编程之HttpClient运用 在 Android开发中我们经常会用到网络连接功能与服务器进行数据的交互,为此Android的SDK提供了Apache的HttpClient来方便我们 ...
- Android 网络编程之HttpURLConnection运用
Android 网络编程之HttpURLConnection 利用HttpURLConnection对象,我们可以从网络中获取网页数据. 01 URL url = new URL("http ...
- 网络编程之Socket代码实例
网络编程之Socket代码实例 一.基本Socket例子 Server端: # Echo server program import socket HOST = '' # Symbolic name ...
- [网络编程之Socket套接字介绍,套接字工作流程,基于TCP协议的套接字程序]
[网络编程之Socket套接字介绍,套接字工作流程,基于TCP协议的套接字程序] 为何学习socket套接字一定要先学习互联网协议: 1.首先:要想开发一款自己的C/S架构软件,就必须掌握socket ...
- Python自动化运维之15、网络编程之socket、socketserver、select、twisted
一.TCP/IP相关知识 TCP/UDP提供进程地址,两个协议互不干扰的独自的协议 TCP :Transmission Control Protocol 传输控制协议,面向连接的协议,通信 ...
随机推荐
- 有关JSP注释
最近学习过滤器的时候,dispatcher可以指定过滤器被Servlet容器拦截的方式,可以是REQUEST.INCLUDE.FORWARD.ERROR,默认是REQUEST方式. 现在有两个filt ...
- Oracle中in和exists的选择
在ORACLE 11G大行其道的今天,还有很多人受早期版本的影响,记住一些既定的规则, 1.子查询结果集小,用IN 2.外表小,子查询表大,用EXISTS 摘自:http://blog.chi ...
- [terminal]Terminal常用快捷键
1. 终端操作 Ctrl+d/exit 退出当前Termina1 Ctrl+l/clear 清除屏幕 Ctrl+Alt+t/Ctrl+shift+n 打开新终端窗口 Ctrl+shift+ ...
- C#继承的用法
using System; namespace 继承 { public class cat { private string _name = null; private int _age = 0; p ...
- C#托管代码与C++非托管代码互相调用
http://www.cnblogs.com/Jianchidaodi/archive/2009/03/11/1407270.html#1473515 http://www.cnblogs.com/J ...
- python实现字体闪图
!/usr/bin/env python from future import print_function import os.path import sys from optparse impor ...
- python (10) 文件夹的创建与文件夹的删除
有时需要在代码中对文件或者文件夹 进行删除,或者添加 导入的包:import os,shutil 新建文件夹 import os,shutil path = os.getcwd() #获得当前目录 # ...
- js方法收藏
1.验证非负数字 //onfocusout="checkQty(this);" function checkQty(obj) { //排除0开头的非法输入 if (obj.valu ...
- android的照片浏览器(一)至返回所有图片文件
今天开始写android的照片浏览器 首先要解决的问题是要得到sdcard下面所有是图片的文件的目录 于是我先写了一个普通的java类 来得到后缀是.jpg,.bmp.png.jpeg的文件 pack ...
- c语言知识(2)
while(n)首先,n在这里被当作了一个条件其次,当n为真时,进入while循环体(A):否则跳出循环继续执行下面部分(B).n为0时条件为假 n不为0条件为真 while(j) { if(j%1 ...