1、java支持流套接字和数据报套接字。流套接字(stream socket)使用传输控制协议(TCP)进行数据传输,而数据报套接字使用用户数据报协议(UDP)。
2、客户端/服务器计算
套接字是两个主机之间逻辑连接的端点,用于发送和接收数据。java对套接字通信的处理非常类似于对输入输出操作的处理。一旦建立连接,客户端和服务器就可以通过套接字进行通信。
①服务器套接字
要创建一个服务器,需要创建一个服务器套接字(server socket),并把它附加到一个端口上,服务器从端口监听连接。
创建一个服务器套接字:
ServerSocket serverSocker = new ServerSocket(port);
注:如果在已经使用的端口上创建服务器套接字,将会引起java.net.BindException异常。
②客户端套接字
创建好服务器套接字后,服务器就可以监听连接:
Socket socket = serverSocket.accept();
这语句会一直等待,直到一个客户端与服务器套接字建立连接。
客户端执行下列语句请求与服务器进行连接:
Socket socket = new Socket(serverName, port);
其中serverName是服务器的Internet主机名或者是IP地址。
注:主机名localhost或者IP地址127.0.0.1可以来引用客户端正在运行的计算机。如果找不到主机
③通过套接字进行数据传输
对套接字对象使用getInputStream()方法和getOutputStream()方法,获得输入流和输出流。使用流DataInputStream、DataOutputStream、BufferReader和PrintWriter包装InputStream和OutputStream,读写int、double或String之类的数据。
建议使用二进制I/O在服务器和客户端之间进行数据传输,效率更高。
3、InetAddress类
使用该类求得客户的主机名和IP地址
①在套接字上为客户端创建InetAddress的一个实例:
InetAddress inetAddress = socket.getInetAddress();
inetAddress.getHostName():获得host name
inerAddress.getHostAddress():获得IP Address
②使用静态方法通过主机名或者IP地址创建InetAddress的一个实例:
InetAddress address = InetAddress.getByName("www.scau.edu.cn");
4、服务多客户
使用线程处理服务器上多个客户同时访问,为了限制连接的并发数目,可以使用一个固定大小的线程池,并且向该线程池添加任务。
5、applet客户端
安全性的限制,applet只能与装入它们的主机进行连接,这样HTML文件必须存放在运行它的服务器所在的机器上。可以在applet上调用getCodeBase().getHost()获取服务器主机的名字。(getCodeBase()返回的URL对象代表了applet文件)
6、发送和接收对象
可以在套接字流上使用ObjectOutputStream和ObjectInputStream发送和接收对象。为了能够进行传输,对象必须是可序列化的。
7、从Web服务器上读取文件
java允许开发通过Web服务器从远程主机上读取文件的客户端程序,不需要创建自定义服务器程序,Web服务器可用于发送文件。
①为了读取一个文件,先要为文件创建一个URL对象。
如果URL字符串出现语法错误,将会有一个MalformedURLException被抛出。
②然后使用定义在URL类中的openStream()方法,对文件的URL打开一个输入流。
现在可以从输入流中读取数据了。
8、JEditorPane类
能自动显示普通文本文件、HTML文件和RTF文件,不必编写专门从文本中读取数据的代码。JEditorPane是JTextComponent的一个子类,因此它继承了JTextComponent的所有行为和属性。
显示文件的内容,使用setPage(URL)方法:
当单击编辑窗格中的超链接时,JEditorPane产生javax.swing.event.HyperlinkEvent事件。通过改时间可以得到超链接的URL,并使用setPage(url)方法显示它。
9、数据报套接字
①DatagramPacket类和DatagramSocket类
利用它们可以编写使用数据报在网络上发送和接收分组的Java程序。
DatagramPacket类:
用于数据报的分组,数据报的分组用来实现无连接的分组传输服务。要为来自客户端的传送创建DatagramPacket对象,可以使用构造方法:
DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port);
//或者DatagramPacket(byte[] buf, int length);
一旦创建了一个数据报分组,就可以使用getData方法和setData方法获取和设置分组中的数据。
DatagramSocket类:
发送和接收数据报分组的套接字,每个在数据套接字上发送或接收的分组都是独立编址和路由。
要创建服务器的数据报套接字DatagramSocket,使用构造方法DatagramSocket(int port),它将套接字绑定在本地主机指定的端口上。
要创建客户端的数据报套接字DatagramSocket,使用构造方法DatagramSocket(),它将套接字绑定到本地主机任意一个可用的端口上。
为了发送数据,需要创建一个分组,填入内容,指定接收机的Internet网址和端口号,并在DatagramSocket对象上调用发送分组的send(packet)方法。
为了接收数据,必须创建一个空的分组,并在DatagramSocket对象上调用接受的分组的receive(packet)方法。
②数据报程序设计
数据报没有服务器套接字ServerSocket的概念,客户端和服务器都用DatagramSocket发送和接收分组。
通常,将一个应用程序设计成服务器,使用指定端口的构造方法DatagramSocket(port)创建数据报套接字DatagramSocket。客户端创建数据报套接字DatagramSocket时可以不指定端口号,在运行时动态地进行选择。当客户端向服务器发送一个分组时,客户端的IP地址和端口号都包含在分组中,服务器能够从分组中提取它们,并利用它们向客户端发回分组。
因为数据报是无连接的,所以一个DatagramPacket对象可以发送给多个客户端,并且多个客户端可以接收来自相同服务器的一个分组。在同一个端口上不能再创建另一个DatagramSocket对象。客户端在一个可用的端口上创建DatagramSocket对象,该套接字的端口号是动态指派的。可以同时开始多个客户端,每个客户端的数据报套接字可能是不同的。
注:流套接字和数据报套接字的端口号是互不相关的,二者可以同时使用同一端口号。