Socket编程
Socket编程
Android平台在网络编程方面与Java别无二致,所用的是同样的机制和方法,操作方式也与普通Java程序保持一致。
TCP/IP协议与Socket编程
TCP/IP——Transmission Control Protocol / Internet Protocol的简写,传输控制协议/Internet协议,又叫网络通讯协议,是Internet最基本的协议,是Internet国际互联网络的基础,简单地说,就是由网络层的IP协议和传输层的TCP协议组成的。
TCP/IP协议遵循的是一个抽象的分层模型,模型中的所有的TCP/IP系列网络协议都被归类到四个抽象的“层”中。每一抽象层建立在低一层提供的服务上,并且为高一层提供服务。完成一些特定的任务需要众多的协议协同工作,这些协议分布在参考模型的不同层中的,因此有时称它们为一个协议栈。
TCP/IP参考模型从下到上分别包括:网络接口层、网络互连层、传输层、应用层。经常使用的包括:HTTP(万维网服务)、FTP(文件传输)、SMTP(电子邮件)、SSH(安全远程登录)、DNS(域名系统)在内的许多协议都被认为运行在TCP/IP协议栈的应用层之上。每一个应用层协议一般都会使用到两个传输层协议之一:面向连接的TCP传输控制协议和无连接的UDP用户数据报文协议。
传输层的协议能够解决诸如端到端可靠性(数据是否已经达到目的地)和保证数据是否按照正确的顺序到达这样的问题。
TCP是一个“可靠的”、面向连接的传输机制,他提供一种可靠字节流以保证数据的完整、无损并且按顺序到达。TCP尽量连续不断地测试网络的负载并且控制发送数据的速度以避免网络过载。另外,TCP试图将数据按照规定的顺序发送。这是它与UDP不同之处,但这在实时数据流或路由高网络层丢失率应用的时候可能成为一个缺陷。
UDP是一个无连接的数据报文协议。它是一个“尽最大努力交付”或者“不可靠”协议,不是因为它特别不可靠,而是因为它不检查数据包是否已经到达目的地,并且不保证他们按顺序到达。如果一个应用需要这些特点,它就必须自己提供或者使用TCP。UDP的典型性应用如:流媒体(音频和视频等)这样“按时到达”比可靠性更重要的应用,或者如DNS查找这样的简单查询/响应的应用,如果建立可靠的连接所做的额外工作将是不成比例得多。
在网络上的两个程序通过一个双向的通信连接实现数据的交换,这个双向链路的一端称为一个Socket。Socket通常用来实现客户方和服务方的连接。Socket是TCP/IP协议的一个十分流行的编程界面,一个Socket由一个IP地址和一个端口号确定。在传统的UNIX环境下可以操作TCP/IP协议的接口不止一个Socket一个,Socket所支持的协议种类也不光TCP/IP一种,因此两者之间没有必然的联系。不过在Java环境下,Socket编程主要指基于TCP/IP协议的网络编程,也就是说在Java环境下实现基于TCP/IP协议的网络编程需要采用Socket机制。
Socket编程比基于URL的网络编程提供了更高传输效率,更强大的功能和更灵活的控制,但是却要更复杂一些。由于Java本身的特殊性,Socket编程在Java中可能已经是层次最低的网络编程接口,在Java中要直接操作协议中更低的层次,需要使用Java的本地方法调用(JNI)。
Android中进行Socket编程与普通Java程序所进行的Socket编程的方式保持一致,不同的是在数据来源以及显示上有所区别。采用Java语言开发的一些网络编程的应用(如:最经典的聊天室)可以很容易就移植到Android平台上。TCP协议要比UDP协议的应用广泛,如:常用的HTTP、FTP、SMTP等协议都是采用TCP协议。
Socket通常用来实现C/S结构。使用Socket进行C/S程序设计的一般连接过程是这样的:Server端监听某个端口是否有连接请求,Client端向Server端发出连接请求,Server端向Client端发回Accept(接受)消息,一个连接就建立起来了。Server端和Client端都可以通过Send、Write等方法与对方通信。Java在包java.net中提供了两个类Socket和ServerSocket,分别用来表示双向连接的Cliet和Server。
Socket和ServerSocket类介绍
服务器端ServerSocket
ServerSocket类常用的构造函数:
(1)ServerSocket()
该构造函数创建ServerSocket对象,没有与任何端口号绑定,不能直接使用,要继续调用bind()方法,才能完成其他构造函数所能完成的功能。
(2)ServerSocket(int port)
该构造函数创建的ServerSocket对象可以将这个ServerSocket绑定到一个指定的端口上,通过改程序所在计算机的IP地址以及这个端口号,客户端Socket才能连接该ServerSocket。
(3)ServerSocket(int port,int backlog)
该构造函数在上一个构造函数的基础上根据backlog指定该ServerSocket可以等待的队列最大长度。
(3)ServerSocket(int port,int backlog,InetAddress bindAddr)
该构造函数在上一个构造函数的基础上可以指定相关的IP地址,这用于计算机上有多个网卡和多个IP的情况。如果没有指定,底层驱动程序会为我们选择一个。
我们一般采用第二个构造函数来创建ServerSocket对象。
注意:在选择端口的时候,必须要小心。每个端口都提供一种特定的服务,只有给出正确的端口,才能获得相应的服务。0~1023的端口号是系统保留的。如:HTTP服务的端口号为:80 。Telnet服务的端口号为21,FTP服务的端口号为23,所以我们在选择端口号时,最好选择一个大于1023的数以防止发生冲突。
ServerSocket还有一个常用的方法accept()。该方法的作用为产生“阻塞”,直到接受到一个连接,并且返回一个客户端Socket对象实例。“阻塞”是一个术语,它使程序运行暂时“停留”在这个地方,直到一个会话产生,然后程序继续;通常“阻塞”是由循环产生的。
客户端Socket
Socket类常用的构造函数有:
(1)Socket()
该构造函数创建Socket对象,不与任何服务器建立连接,不能直接被使用,需要调用connect()方法才能完成与其他构造函数一样的功能。若想用同一个Socket对象连接多个服务器,则可以使用该构造函数创建Socket对象后,不断调用connect()方法连接每个服务器。
(2)Socket(String host,int port)
根据两个参数连接指定的主机地址和端口号上运行的服务器程序。
(3)Socket(InetAddress address,int port)
根据两个参数连接指定的主机地址和端口号上运行的服务器程序。与第二个构造函数不同的是它的第一个参数是一个InetAddress对象。
经常采用第二个构造函数来构造Socket对象。
在创建Socket时如果发生错误,将产生IOException,在程序中必须对之进行处理。所以创建Socket或ServerSocket时必须捕获或抛出异常。
Socket常用方法:
(1)getInputStream()
返回此套接字的输入流,通过得到的输入流可以获取信息。
(2)getOutputStream()
返回此套接字的输出流,通过得到的输出流可以获取信息。
可以在返回的输入/输出流对象上建立过滤流,如:DataInputStream、DataOutputStream或PrintStream类对象,对于文本流对象,可以采用InputStreamReader、OutputStreamWriter、PrintWriter等处理。
关闭Socket的方法
每一个Socket存在时,都将占用一定的资源,在Socket对象使用完毕时,将其关闭。关闭Socket可以调用Socket的Close()方法。在关闭Socket之前,应将与Socket相关的所有的输入/输出流全部关闭,以释放所有的资源。而且要注意关闭的顺序,与Socket相关的所有的输入/输出流首先关闭,然后关闭Socket。
Socket通信的一般过程
(1)服务器端程序创建一个ServerSocket,然后调用accept()方法等待客户连接。
(2)客户端程序创建一个Socket并请求与服务器程序建立连接。
(3)服务器端程序接受客户端的连接请求,并创建一个新的Socket与客户端建立专线连接。
(4)建立了连接的客户端及服务器端的两个Socket在一个由服务器端程序创建的单独线程上对话,对话的方式是采用getInputStream()、getOutputStream()得到的输入和输出流进行读取与输出。
(5)服务器端开始等待新的连接请求,重复(2)~(5)的过程。
posted on 2013-05-20 17:30 Harvey Ren 阅读(2510) 评论(0) 编辑 收藏 举报