android客户端与服务端通信
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1. 网络的基础知识
ip:主机在网络中的唯一标识,是一个逻辑地址。127.0.0.1表示本机地址
端口:是一个为了便于实现服务器与客户端之间通信所使用的抽象概念。
协议:通讯双方为了完成预先制定好的功能而达成的约定。
TCP/IP网络7层模型:物理层Physical(硬件)、数据链路层DataLink(二进制)、网络层Network(IP协议:寻址和路由)、
传输层Transport(TCP、UDP协议)、会话层Session(端口)、表示层Presentation、
应用层Application(HTTP、FTP、SMTP、POPS、DNS)
TCP协议和UDP协议:
TCP:开销大,用于可靠性要求高的场合,TCP的过程就是像打电话的过程。面向连接,可靠,低效
UDP:用在对实时性要求比较高的场合。UDP过程相当于写信的过程。无连接,不可靠,效率高。
2.网络套接字Socket(TCP)
客户端要创建的对象Socket 服务器端要创建的对象ServerSocket。
创建一个TCP服务器端程序的步骤:
a.创建一个ServerSocket
b.从ServerSocket接受客户连接请求
c.创建一个服务线程处理新的连接
d. 在服务线程中,从socket中获得I/O流
e. 对I/O流进行读写操作,完成与客户的交互
f.关闭I/O流
g.关闭Socket
创建一个TCP客户端程序的步骤:
a. 创建Socket
b. 获得I/O流
c.对I/O流进行读写操作
d. 关闭I/O流
e. 关闭Socket
3.为多个客户端服务
服务器端可以处理多个客户端的请求,那么服务器端要有类似以下的代码实现:
while(true){
Socket socket=serverSocket.accept();
Runnable r=new TestThread(socket);
Thread t=new Thread(r);
t.start(); }
TestThread实现了Runnable接口,在它的run方法中包含了与客户端循环通信的代码。
class TestThread implements Runnable{........
public void run(){
try{ ..........;}
catch(IOException e){handle exception}
} }
4. 建立URL连接
1)URL和URI URL和URLConnection类封装了大量复杂的实现细节,这些细节涉及如何从远程站点获取信息。可以通过传递一个字符串来构建一个URL对象,URL url=new URL(urlString);获得资源内容InputStream in=url.openStream();
URL:统一资源定位符URI:统一资源标示符
在JAVA类库中URI类不包含任何用于访问资源的方法,它的唯一作用就是解析;URL类可以打开一个到达资源的流,因此URL类只能作用于Java类库知道该如何处理的模式,如http:、https:、ftp:、本地文件系统file:、JAR文件jar:
2)使用URLConnection获取资源
操作URLConnection对象的步骤:
a.调用URL类中的openConnection()获得URLConnection对象。
URLCOnnection connection=url.openConnection();
b.设置任意的请求属性
c.调用connect()连接远程资源connection.connect();//除了与服务器建立套接字连接外,还可向服务器查询头信息.
d.与服务器建立连接后,可以查询头信息。getHeaderFieldKey和getHeaderField()两个方法列举消息头所有字段。
e.最后访问资源
URLConnectin类的方法:a.先介绍几个可以与服务器建立连接之前设置连接属性的方法
setDoInput()和setDoOutput(),默认情况下建立的连接只有从服务器读取信息的输入流,并没有任何执行写操作的输出流。要想获得输出流(如想服务器提交一个数据),既要调用connection.setDoOutput(true);
setIfModifiedSince()用于告诉连接你只对自某个特定日期依赖修改过的数据感兴趣;
setUseCaches和setAllowUserInteraction():之用于applet。前一个方法命令浏览器首先检查它的缓存,后一个则用于在访问有密码保护的资源是弹出对话框,以便查询用户名和密码。
setRequestProperty():用来设置对特定协议起作用的任何“名-值对”//如访问一个有密码保护的Web页connection.
setRequestProperty("Authorization","Basic"+new
sun.misc.BASE64Encoder().encode(input.getBytes));
b.与服务器建立连接后使用的方法:
getHeaderFieldKey(n):获得响应头的第n个值其中n从1开始。
getHeaderFields(n):得到第n个值。
3)base64编码:用于将字节流编码成可打印的ASCII字符流。
代码如下:{ByteArrayOutputStream bOut=new ByteArrayOutputStream();
Base64OutputStream out=new Base64OutputStream(bOut);
try{out.write(s.getBytes());out.flush();}
catch(IOException e){}
return bOut.toString(); }
关于编码,我们看看这两个类URLEncoder和URLDecoder
URLEncoder.encode(String s,String encoding)采用指定的字符编码模式对字符串s进行编码,如按UTF-8编码;
URLDecoder.decode(String s,String encoding)采用指定编码模式对已编码字符串s进行解码,并返回结果。
5 高级套接字编程
1)套接字超时:在实际应用中,我们可能并不想从套接字读取信息,因为在数据可以被访问之前,读操作将会被阻塞,如果此时主机不可达,那么我们的应用将要等待很长的时间,并且因为受底层操作系统的限制而最终会导致超时。
解决方案:在构造socket对象时设置超时值
Socket s=new Socket(String host,int port); s.setSoTimeout(10000);或
Socket s=new Socket(); s.connect(new InetSocketAddress(host,port),timeout);
注意:如果设置了超时值,并且以后的读操作和写操作在没有被完成之前就超过了时间限制,那么这些操作就会抛
出SocketTimeoutException异常。
2)可中断套接字:当连接一个套接字,当前线程会被阻塞知道建立连接或超时为止,同样当通过套接字读取数据或写时,当前线程也会被阻塞知道操作成功或超时为止,这个时候我们就要有一个功能用以取消那些看似不会成功的连接,即中断套接字。
为了中断套接字操作,可以使用java.nio包提供的一个特性—SocketChannel类;
SocketChannel channel=SocketChannel.open(new