Android必备:Android Socket编程的了解与学习整理

看这里:Android必备:Android Socket编程的了解与学习整理

最近学习Android的过程中,由于项目、业务等因素影响,服务端通过Socket进行通信,于是开始学习Socket编程,之前的开发中,很少涉及此 方面的知识学习,本篇就来简单的整理一下,通过Android客户端进行Socket登录的demo,来进行Adnroid Socket编程的学习。

在开始学习之前,先来了解一下Socket,以下内容来自百度百科

通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。

首先,来介绍一下项目的设计,只包含两个UI布局文件:login.xml和main.xml,对应登录页和主页,登录页包含一个用户名的输入框和登录按 钮,点击登录按钮,登录按钮显示文字“正在连接,请稍候...”,通过Socket进行登录,并跳转到主页,如果用户名是admin,则在主页显示“登录 成功!”反之显示“登录失败!”。

下面是demo运行后的具体效果图:

login.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="wrap_content"
        >
    <EditText
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:inputType="textPersonName"
            android:hint="请输入用户名"
            android:ems="10"
            android:id="@+id/loginName"
            />
    <Button
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:text="登录"
            android:id="@+id/loginBtn"
            />

</LinearLayout>

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:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:gravity="center"
        android:id="@+id/mainText"
        />
</LinearLayout>

当然通过Socket进行通信的时候,我们需要app拥有网络访问即Internet或Wifi的权限,将下面两行添加到AndroidManifest.xml:

    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.INTERNET"/>

下面开始进行实例的编写,本篇的学习基于TCP/ IP 进行Socket通信,说是Android Socket编程,其实使用的是java.net包下提供的ServerSocket和Socket类,这是一种比较底层的编程方式,Socket类用来建立客户端程序,ServerSocket用来建立服务端程序,首先来看服务端的代码:

package com.xx566.socket.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketServer {

    private static ServerSocket serverSocket;

    public static void main(String[] args) throws IOException {
        serverSocket = new ServerSocket(8888);
        while (true) {
            final Socket socket = serverSocket.accept();
            try {
                // 获取输入流
                BufferedReader inputStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                // 获取输出流
                PrintWriter outputStream = new PrintWriter(socket.getOutputStream());
                // 读取输入
                String readString = inputStream.readLine();
                if ("admin".equals(readString)) {
                    outputStream.println("登录成功!");
                } else {
                    outputStream.println("登录失败!");
                }
                outputStream.flush();
                // 关闭
                outputStream.close();
                inputStream.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

我们在8888端口,实例化了Socket服务端,通过永真循环,来等待客户端Socket的连接。accept()方法返回一个对应客户端的Socket,服务端读取客户端输入,如果输入的是"admin",则输出"登录成功!",反之,输出"登录失败!",接下来,我们主要来看一下客户端LoginActivity的编写,需要注意的是,在Android4.0系统以上的系统中,是不允许在主线程中执行网络相关的请求,否则会抛出NetworkOnMainThreadException异常,所以需要单独的线程向服务端发送Socket,完整代码如下:

package com.xx566.socket;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import java.io.*;
import java.net.Socket;

public class LoginActivity extends Activity {

    private Button loginBtn;
    private EditText loginName;
    PrintWriter outputStream;
    BufferedReader inputStream;
    Socket socket;
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            //通过handler处理接收到的消息
            if (msg.what == 1) {
                //跳转到主页面,显示登录结果
                Intent intent = new Intent(LoginActivity.this, MainActivity.class);
                intent.putExtra("result", msg.getData());
                startActivity(intent);
            }
        }
    };

    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.login);
        //登录按钮点击事件
        loginBtn = (Button) findViewById(R.id.loginBtn);
        loginName = (EditText) findViewById(R.id.loginName);
        loginBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //点击登录后,显示正在连接服务器
                loginBtn.setText("正在连接,请稍候...");
                loginBtn.setClickable(false);
                final String userName = loginName.getText().toString();
                //通过Socket登录服务器,简单的传递用户名
                new Thread() {
                    @Override
                    public void run() {
                        //处理接收到的消息
                        Message message = new Message();
                        message.what = 1;
                        Bundle bundle = new Bundle();
                        String result = "";
                        try {
                            socket = new Socket("192.168.0.32", 8888);
                            outputStream = new PrintWriter(socket.getOutputStream());
                            inputStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                            outputStream.println(userName);
                            outputStream.flush();
                            //读取结果
                            while (true) {
                                result = inputStream.readLine();
                                if (!"".equals(result)) {
                                    break;
                                }
                            }
                            //关闭
                            inputStream.close();
                            outputStream.close();
                            socket.close();
                        } catch (Exception e) {
                            result = "网络异常!";
                        }
                        bundle.putString("result", result);
                        message.setData(bundle);
                        //传递消息
                        handler.sendMessage(message);
                    }
                }.start();
            }
        });

    }

    @Override
    protected void onResume() {
        super.onResume();
        loginBtn.setText("登录");
        loginBtn.setClickable(true);
    }
}

这里使用了Android Handler机制进行了线程间消息的传递,主要是接收服务端响应的结果,启动MainActicity。MainActivity里面显示登录结果,代码如下:

package com.xx566.socket;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends Activity {

    private TextView mainText;
    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mainText = (TextView) findViewById(R.id.mainText);
        Bundle bundle = getIntent().getExtras().getBundle("result");
        mainText.setText(bundle.getString("result"));
    }
}

完整项目地址:http://git.oschina.net/realfighter/SocketDemo

时间: 2024-10-04 07:52:19

Android必备:Android Socket编程的了解与学习整理的相关文章

winsock教程- windows下的socket编程(c语言实现)

winsock教程- windows下的socket编程(c语言实现) 使用winsock进行socket 编程 这是一个学习windows下socket编程(c语言)的快速指南.这是因为一下代码片段只能运行在windows下.windows API中的socket编程部分叫做winsock. 你电脑上做出的任何网络通信背后基本上都有socket,它是一个网络的基本组成部分.举个例子说当你在浏览器键入www.google.com的时候,socket连接到google.com并且取回那个页面然后才

iOS项目开发之Socket编程

有一段时间没有认真总结和写博客了 前段时间找工作.进入工作阶段.比较少静下来认真总结,现在静下心来总结一下最近的一些心得 前言 AsyncSocket介绍 AsyncSocket详解 AsyncSocket示例 一.前言 公司的项目用到了Socket编程,之前在学习的过程当中,用到的更多的还是http请求的方式.但是既然用到了就必须学习一下,所以就在网上找一些例子,然后想自己写一个demo.可是发现很多写iOS Socket的博客并没有很详细的说明,也可能是大神们觉得其他东西都浅显易懂. 自己专

Android应用开发提高篇(4)-----Socket编程(多线程、双向通信)(转载)

转自:http://www.cnblogs.com/lknlfy/archive/2012/03/04/2379628.html 一.概述 关于Socket编程的基本方法在基础篇里已经讲过,今天把它给完善了.加入了多线程,这样UI线程就不会被阻塞:实现了客户端和服务器的双向通信,只要客户端发起了连接并成功连接后那么两者就可以随意进行通信了. 二.实现 在之前的工程基础上进行修改就可以了. MyClient工程的main.xml文件不用修改,只需要修改MyClientActivity.java文件

Android Socket编程学习笔记

通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.在Internet上的主机一般运行了多个服务软件,同时提供几种服务.每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务. 网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket.Socket通常用来实现客户方和服务方的连接.Socket是TCP/IP协议的一个十分流行的编程界面,一个Socket由一个IP地址和一个端口号唯一确定. 在java中,Socke

android开发系列之socket编程

上周在项目遇到一个接口需求就是通讯系列必须是socket,所以在这篇博客里面我想谈谈自己在socket编程的时候遇到的一些问题. 其实在android里面实现一个socket通讯是非常简单的,我们只需要在代码里面实现一个Socket对象,同时在该对象里面传进一个ip/port,同时设置一些超时时间就可以了.代码如下: public class SocketThread extends Thread { private String ip = "192.168.129.1"; priva

Android Socket编程

花了大概两天的时间,终于把Android的Socket编程给整明白了.抽空和大家分享一下: Socket Programming on Android Socket 编程基础知识: 主要分服务器端编程和客户端编程. 服务器端编程步骤: 1: 创建服务器端套接字并绑定到一个端口上(0-1023是系统预留的,最好大约1024) 2: 套接字设置监听模式等待连接请求 3: 接受连接请求后进行通信 4: 返回,等待赢一个连接请求 客户端编程步骤: 1: 创建客户端套接字(指定服务器端IP地址与端口号) 

Socket编程总结—Android手机服务器与多个Android手机客户端之间的通信(非阻塞)

根据前两周写的关于Socket编程的网络通信的代码,现在对有关知识和注意事项进行总结如下: 1.首先说下Android NIO中有关Socket编程的类: 1)ServerSocketChannel类:服务器套接字通道相当于传统IO下的ServerSocket,通过ServerSocketChannel的socket()可以获得传统的ServerSocket,反过来使用ServerSocket的getChannel()可以获得ServerSocketChannel对象:实例化ServerSock

Android的Socket编程尝试失败了,求帮助

============问题描述============ 服务器端:把客户端传来的int加1,传回去 public class Server extends Thread { @Override public void run() { // TODO Auto-generated method stub try { ServerSocket serverSocket=new ServerSocket(10000); System.out.println("Start Server");

android Socket编程注意点

1.对Socket的操作放在非UI线程内进行 ??在Android应用中,为了保证APP的用户体验,必须对用户的操作尽可能快的做出响应,因此在以前的Android版本中,不建议将耗时的操作放在UI线程中.到Android3.0之后的版本,则是更进一步做了限制,在非UI线程中禁止操作UI,在UI线程中禁止做响应时间长的操作,如联网操作. ?? 如果在UI线程中进行联网操作的话,会抛出NetworkOnMainThread异常,因此,Socket操作必须放在子线程内进行 2.要保持Socekt实例的