java 网络编程TCP程序设计
一.TCP/IP知识
1.网络编程的目的就是指直接或间接地通过网络协议与其它计算机进行通讯。
2. 网络编程中有两个主要的问题:一个是如何准确地定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效地进行数据传输。
3.TCP/IP(Transmission Control Protocol Internet Protocol的简写,中文译名为传输控制协议/互联网络协议)协议,是Internet最基本的协议,简单地说,就是由底层的IP协议和TCP协议组成的。
4.在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可以唯一地确定Internet上的一台主机。
5. TCP层则提供面向应用的可靠的或非可靠的数据传输机制,这是网络编程的主要对象,一般不需要关心IP层是如何处理数据的。
6.使用Java语言编写网络通信程序通常是在应用层,对某些特殊的应用可能需要直接基于传输层协议编程,一般无需关心网络通信的具体细节,特别是互联网层和网络接口层。
7.传输层提供在源结点和目标结点的两个进程实体之间提供可靠的端到端的数据传输,TCP/IP模型提供了两种传输层协议,即传输控制协议TCP和用户数据报协议UDP。
8.TCP协议是面向连接的,在传送数据之前必须与目标结点建立连接,数据传输结束后关闭连接。
9. UDP是一种无连接协议,可直接传输数据,无需事先建立连接,直接发送带有目标结点信息的数据报。
10.不同的数据报可能经过不同的路径到达目标结点,到达时的顺序与出发时的顺序也可能不同。
11.采用哪种传输层协议是由应用程序的需要决定的,如果可靠性更重要的话,用面向连接的协议会好一些。比如文件服务器需要保证数据的正确性和有序性,如果一些数据丢失了,系统的有效性将会失去。
12. 而有一些服务器是间歇性地发送一些数据块的,如果数据丢失,服务器并不需要再重新发送,因为当数据到达的时候,它可能已经过时了。确保数据的有序性和正确性需要额外的操作和存储空间,这将会降低系统的响应速率。
13.传输层的上一层是应用层,应用层包括所有的高层协议。早期的应用层有远程登录协议(Telnet)、文件传输协议(File Transfer Protocol ,FTP)和简单邮件传输协议(Simple MailTransfer Protocol ,SMTP)等。目前使用最广泛的应用层协议是用于从Web服务器读取页面信息的超文本传输协议(Hyper Text Transfer Protocol,HTTP)。
14.端口(Port)与IP地址一起为网络通信的应用程序之间提供一种确切的地址标识,IP地址标识了发送数据的目的计算机,而端口标识了将数据包发送给目的计算机上的哪一个应用程序。
15. 应用层协议通常采用客户/服务器模式,应用服务器启动后监听特定的端口,客户端需要服务时请求与服务器该端口建立连接。一些常用的应用服务都有缺省的端口,例如Web服务器缺省的端口号为80。
16.域名是为了方便记忆而专门建立的一套地址转换系统,一个域名只能对应一个IP地址,而多个域名可以同时被解析到一个IP地址。
17. 要访问一台互联网上的服务器,最终还必须通过IP地址来实现,域名解析就是将域名重新转换为IP地址的过程。域名解析需要由专门的域名解析服务器(DNS)来完成。
18.获取本机的IP地址
import java.net.*; public class getLocalHostTest { public static void main(String[] args) { InetAddress myIP=null; // InetAddress用来存储internet地址 try { myIP=InetAddress.getLocalHost(); } catch(Exception e) { } System.out.println(myIP); } }
19.根据域名自动到DNS上查找IP地址
import java.net.*; public class getIP { public static void main(String args[]) { InetAddress bd=null; try { bd=InetAddress.getByName("www.baidu.com"); } catch(Exception e) { } System.out.println(bd); } }
二. 网络编程的基本方法
1.Java语言专门为网络通信提供了软件包java.net。采用java.net包提供的API可以快速方便地开发基于网络的应用。
2.java.net包对http协议提供了特别的支持。只需通过URL类对象指明图像、声音资源的位置,无需额外的工作,就可以轻松地从Web服务器上获取图像、声音,或者通过流操作获取HTML文档及文本等资源,并可以对获得的资源进行处理。
3.java.net包还提供了对TCP、UDP协议套接字(Socket)编程的支持,可以建立用户自己的服务器,实现特定的应用。
4.Socket是一种程序接口,最初由California大学Berkeley分校开发,是用于简化网络通信的一种工具,是UNIX操作系统的一个组成部分。现在Socket的概念已深入到各种操作环境,包括Java。
三.Socket(套接字)
1.套接字(Socket)是由伯克利大学首创的。它允许程序把网络连接当成一个流,可以向这个流写字节,也可以从这个流读取字节。套接字为程序员屏蔽了网络的底层细节,例如媒体类型、信息包的大小、网络地址、信息的重发等。
2.网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。Socket通常用来实现客户方和服务方的连接。Socket是TCP/IP协议的一个十分流行的编程界面,一个Socket由一个IP地址和一个端口号唯一确定。
3.对于一个功能齐全的Socket,都要包含以下基本结构,其工作过程包含以下四个基本的步骤: (1)创建Socket; (2)打开连接到Socket的输入/出流; (3)按照一定的协议对Socket进行读/写操作; (4)关闭Socket。 第(3)步是程序员用来调用Socket和实现程序功能的关键步骤。
4.为了在TCP上通信,客户端和服务器端的应用程序需要建立并约束在Socket上。
5.Socket类的对象以流的形式在客户端和服务器端之间通信。
6.Socket类支持TCP/IP的基本类。TCP是一个流网络连接协议。Socket类提供一些流输入/输出的方法,使得从Socket中读入数据和往Socket中写入数据都很容易。该类对于在Internet上进行通信是必不可少的。
四.客户方套接字
1.客户端套接字主要涉及到以下方法:
public Socket(String host ,int port)
2.这个方法建立一个到主机host、端口号为port的套接字,连接到远程主机。 创建一个Socket的实例对象:
Socket client=new Socket(“服务器名”,1111);
3.客户机必须知道服务器的IP地址。可以利用前面提到的InetAddress 对象通过域名来得到。
示范代码如下:
try { Socket soc=new Socket ("www.sina.com" , 80);//发送数据 } catch(unknownHostException uex) { } catch(IOException e) {}
4.public InputStream getInputStream( ) throws IOException
该方法返回一个输入流,利用这个流就可以从套接字读取数据。通常链接这个流到一个 BufferedInputStream或者BufferedReader。
5.public OutputStream getOutputStream ( ) throws IOException
该方法返回一个原始的OutputStream,可以从应用程序写数据到套接字的另一端。通常将它链接到DataOutputStream或者OutputStreamWriter等更方便的类
五.服务器套接字
1.在ServerSocket类中包含了创建ServerSocket对象的构造方法、在指定端口监听的方法、建立连接后发送和接收数据的方法。
2.当创建ServerSocket类的一个实例对象并提供一个端口资源,就建立了一个固定位置可以让其他计算机来访问:
ServerSocket server=new ServerSocket(1234);
3.注意:端口的分配必须是唯一的。因为端口是为了唯一标识每台计算机唯一服务的,另外端口号是从0~65535之间的,前1024个端口已经被TCP/IP 作为保留端口,因此所分配的端口只能是1024个之后的。
4.ServerSocket类是一个用于监听客户请求的的Internet服务器程序的类。ServerSocket类实际上并不执行服务,在服务器上代表客户创建一个Socket类的对象,通过创建该对象来进行通信。
5.下面是一个典型的创建Server端ServerSocket的过程。
ServerSocket server=null; try { server=new ServerSocket(4700); //创建一个ServerSocket在端口4700监听客户请求 }catch(IOException e) {System.out.println("can not listen to :"+e); }
Socket socket=null; try { socket=server.accept();//接受连接请求 }catch(IOException e){ System.out.println("Error:"+e); }
6.每一个Socket存在时,都将占用一定的资源,在Socket对象使用完毕时,要将其关闭。关闭Socket可以调用Socket的Close()方法。
7.在关闭Socket之前,应将与Socket相关的所有的输入/输出流全部关闭,以释放所有的资源。而且要注意关闭的顺序,与Socket相关的所有的输入/输出该首先关闭,然后再关闭Socket。
8.发送方和接收方的成对的两个socket之间必须建立连接,以便在TCP协议的基础上进行通信。当一个socket(通常都是server socket)等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送或接收操作。
9.Socket机制用到的类有java.net.ServerSocket、java.net.Socket等。
10.服务器端实例化ServerSocket类,以accept()方法接收客户的连接。
11.客户端则直接以服务器的地址和监听端口为参数实例化Socket类,连接服务器。
12.服务器端和客户端调用getInputStream()和getOutputStream()方法得到输入/输出流。
13.编写程序实现简单的两台计算机之间的通讯。
服务器:
import java.io.*; import java.net.*; public class MyServer { public static void main(String[] args) throws IOException { ServerSocket server=new ServerSocket(1111); Socket client=server.accept(); BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream())); PrintWriter out=new PrintWriter(client.getOutputStream()); while(true) {String str=in.readLine(); System.out.println(str); out.println("has receive...."); out.flush(); if(str.equals("end")) break; } client.close(); }}
客户端:
import java.net.*; import java.io.*; public class Client{ static Socket server; public static void main(String[] args) throws Exception { server=new Socket(InetAddress.getLocalHost(),1111); BufferedReader in=new BufferedReader(new InputStreamReader(server.getInputStream())); PrintWriter out=new PrintWriter(server.getOutputStream()); BufferedReader wt=new BufferedReader(new InputStreamReader(System.in)); while(true) { String str=wt.readLine(); out.println(str); out.flush(); if(str.equals("end")) { break; } System.out.println(in.readLine()); } server.close(); } }