Android学习笔记(14)————Socket在Android上面的应用

/********************************************************************************************
* author:conowen@大钟
* E-mail:conowen@hotmail.com
* http://blog.csdn.net/conowen
* 注:本文为原创,仅作为学习交流使用,转载请标明作者及出处。

********************************************************************************************/


1、Socket的简介

通常来说,Socket也称为“套接字”。从字面上面来看,socket的中文意思为“插座”。举个例子,一台服务器可能会提供很多服务,每种服务对应一个Socket,(也可以这么说,每个Socket就是一个插座,客户若是需要这种服务,就将插头到相应的插座上面就行了)而客户的“插头”也是一个Socket。服务端要和客户端通信,两者都要实例化一个Socket。

Java在包java.net里面提供了两个类:ServerSocket和Socket,前者用于实例化服务器的Socket,后者用于实例化客户端的Socket,也就是说服务器和客户端的Socket是不一样的。


2、Socket的通信过程简单描述

通常来说,我们只需要构造客户端的Socket来和目标服务器通信即可,但是为了方便演示,下面假设服务器也是我们自己架构。

2.1、首先,构造客户端Socket

构造客户端的Socket方法有以下几种,参数里面通常都是指向目标服务器的IP地址、目标服务器的端口号,目标服务器的主机名。

://注意,0~1023端口为系统保留,用户设定的端口号应该大于1023

Socket client=new Socket("192.168.1.23", 2012); //第一个参数是目标服务器的ip地址,2012是目标服务器的端口号

proxy为代理服务器地址,dstaddress为目标服务器ip地址,dstport为目标服务器的端口号,(因为服务器的每种服务都会绑定在一个端口上面),dstName为目标服务器的主机名。

2.2、然后再构造服务器的ServerSocket

构造服务器的Socket有以下几种

如:

ServerSocket socketserver=new ServerSocket(2012); //2012表示服务器要监听的端口号



构造完ServerSocket 之后,需要调用ServerSocket.accept()方法来等待客户端的请求(因为socket都是绑定在端口上面的,所以知道那个客户端请求的)。

accept()方法就会返回请求这个服务的客户端的socket实例。然后通过返回的这个socket实例的方法,操作传输过来的信息。操作方法见2.3~

public Socket accept ()(阻塞函数,也就是说该方法被调用后,就会等待客户端的请求,直到有一个客户请求连接,才返回socket实例)
Since: API Level 1

Waits for an incoming request and blocks until the connection is opened. This method returns a socket object representing the just opened connection.

Returns
  • the connection representing socket.
Throws
IOExceptionif an error occurs while accepting a new connection.

2.3、首先明白一点,Socket通信是通过输入输出流来通信的。

Socket提供了getInputStream()和getOutputStream()方法来获取和发送IO流。注:ServerSocket 的实例没有这两种方法。在服务器中通过调用ServerSocket.accept()方法,来获取客户端的socket对象,才能使用这两种方法。


getInputStream()和getOutputStream()方法分别返回InputStream和OutputStream类对象。


2.4、回收资源

虽然系统会自动回收资源,但是还是建议用户自己手动去回收资源。

每个Socket开启时,都会占用系统的资源,当Socket对象操作完毕之后,应该将其关闭。(服务器的socket和客户端的socket都需要关闭)

在关系socket之前,要确保所有的socket输入输出流都已经关闭。

outstream.close(); intstream.close(); clientsocket.close();

3、简单聊天Demo

该Demo包括服务器和客户端,服务器是编译在计算机的“命令提示符界面”运行的,客户端编译在Android模拟器中运行。然后由Android模拟器与计算机上面的服务器程序聊天通信。(注意:Demo比较简陋,只能执行一次发送操作,如执行多次,就会造成堵塞,可以用多线程去解决,读者可以参考之前的博文,自定义代码就行)

另外,这样通信的话,中文会有乱码,解决方法:编码转码就行,详细过几天再写博文解说

服务器效果图


客户端效果图


3.1、服务器源代码编译于执行方法:


是自己创建一个java文件,然后用命令提示符界面去跳转到java文件的目录下,执行如下命令

javac SocketSer.java 编译通过之后执行如下命令运行//SocketServer为服务器的class名字,用户可以自定义

java SocketServer


3.2、服务器的源代码如下:

/*author:conowen * date:2012.3.5 */ 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 { public static void main(String[] args) throws IOException { ServerSocket socketserver=new ServerSocket(8025);// 新建serversocket,端口号设置为8025 System.out.println("会话开始……"); Socket socketclient = socketserver.accept();// 获取客户端socket的对象 // 从socketclient获得一个输入对象,以便接收从客户端送来的数据 BufferedReader socketinput = new BufferedReader(new InputStreamReader( socketclient.getInputStream())); //获取一个输出对象,以便把服务器的信息返回给客户端 PrintWriter socketoutput = new PrintWriter( socketclient.getOutputStream(), true); while (true) { String temp = socketinput.readLine();//读取输入对象的信息 System.out.print("客户端:"); System.out.println(temp); socketoutput.println("Server:I get it!");//把信息返回给客户端 } } }

3.3、客户端源代码


客户端为Android的工程

用eclipse编译即可

代码如下

/*author:conowen * date:2012.3.5 */ package com.conowen.mysocket; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; 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; public class MySocketActivity extends Activity { EditText display; EditText input; static final int PORT = 8025;// 端口号 static final String IPADD = "192.168.31.164";// 服务器的ip地址 /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button sendbt = (Button) findViewById(R.id.bt);// 发送按钮 display = (EditText) findViewById(R.id.et1);// 用来显示服务器返回来的信息 input = (EditText) findViewById(R.id.et2);// 用来获取客户端的输入信息 sendbt.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub try { String socketstr = input.getText().toString();// 获取EditText的内容 Socket client = new Socket(IPADD, PORT);// 新建一个socket // 从Socket获取一个输出对象,以便把EditText输入的数据发给客户端 PrintWriter socketoutput = new PrintWriter(client .getOutputStream(), true); socketoutput.println(socketstr);// 发送给服务器 socketoutput.flush();// 清空缓存 // 从客户端的socket获取一个输入的对象,以便接收来自服务器信息 BufferedReader socketinput = new BufferedReader( new InputStreamReader(client.getInputStream())); String textviewstr = socketinput.readLine();// 把输入对象的内容读取出来 display.setText(textviewstr);// 显示内容 } catch (Exception e) { // TODO: handle exception } } }); } }

最后记得在Androidmanifest.XML文件加入网络权限

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









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值