当前位置: 首页 > news >正文

目前网站开发主要有哪些工具建设单位网站经费请示

目前网站开发主要有哪些工具,建设单位网站经费请示,个人怎样建立网站,六安亿联网络科技有限公司9.1 网络通信协议 通过计算机网络可以实现多台计算机连接#xff0c;但是不同计算机的操作系统和硬件体系结构不同#xff0c;为了提供通信支持#xff0c;位于同一个网络中的计算机在进行连接和通信时必须要遵守一定的规则#xff0c;这就好比在道路中行驶的汽车一定要遵…9.1 网络通信协议 通过计算机网络可以实现多台计算机连接但是不同计算机的操作系统和硬件体系结构不同为了提供通信支持位于同一个网络中的计算机在进行连接和通信时必须要遵守一定的规则这就好比在道路中行驶的汽车一定要遵守交通规则一样。在计算机网络中这些连接和通信的规则被称为网络通信协议它对数据的传输格式、传输速率、传输步骤等做了统一规定通信双方必须同时遵守才能完成数据交互。 网络通信协议有很多种目前应用最广泛的是TCP/IP协议Transmission Control Protocol/Internet Protocol传输控制协议/英特网互联协议、UDP协议User Datagram Protocol用户数据报协议、ICMP协议Internet Control Message ProtocolInternet 控制报文协议和其他一些协议的协议组。 本章中所学的网络编程知识主要就是基于TCP/IP协议中的内容。在学习具体的内容之前首先来了解一下TCP/IP 协议。TCP/IP又称TCP/IP协议簇是一组用于实现网络互连的通信协议其名称来源于该协议簇中两个重要的协议TCP协议和IP协议。 基于TCP/IP的参考模型将协议分成四个层次。 TCP/IP协议中的四层分别是链路层、网络层、传输层和应用层每层分别负责不同的通信功能接下来针对这四层进行详细地讲解。 ● 链路层也称为网络接口层该层负责监视数据在主机和网络之间的交互。事实上TCP/IP本身并未定义该层的协议而由参与互连的各网络使用自己的物理层和数据链路层协议与TCP/IP的网络互联层进行连接。 ● 网络层也称网络互联层是整个TCP/IP协议的核心它主要用于将传输的数据进行分组将分组数据发送到目标计算机或者网络。 ● 传输层主要使网络程序进行通信在进行网络通信时可以采用TCP协议也可以采用UDP协议。 ● 应用层主要负责应用程序的协议如HTTP协议、FTP协议等。 9.1.1 IP地址和端口号 要想使网络中的计算机能够进行通信必须为每台计算机指定一个标识号通过这个标识号指定接收数据的计算机或者发送数据的计算机。在TCP/IP协议中这个标识号就是IP地址它可以唯一标识一台计算机。目前IP地址广泛使用的版本是IPv4它由4个字节大小的二进制数来表示如00001010000000000000000000000001。由于二进制形式表示的IP地址非常不便记忆和处理因此通常会将IP地址写成十进制的形式每个字节用一个十进制数字(0-255)表示数字间用符号“.”分开如 “10.0.0.1”。 随着计算机网络规模的不断扩大对IP地址的需求也越来越多IPv4这种用4个字节表示的IP地址将面临使用枯竭的局面。为解决此问题IPv6 便应运而生。IPv6使用16个字节表示IP地址它所拥有的地址容量约是IPv4的8×1028倍达到2128个算上全零的这样就解决了网络地址资源数量不足的问题。 IP地址由两部分组成即“网络.主机”的形式其中网络部分表示其属于互联网的哪一个网络是网络的地址编码主机部分表示其属于该网络中的哪一台主机是网络中一个主机的地址编码二者是主从关系。 IP地址总共分为5类常用的有3类介绍如下。 ● A类地址由第一段的网络地址和其余三段的主机地址组成范围是1.0.0.0到127.255.255.255 ● B类地址由前两段的网络地址和其余两段的主机地址组成范围是128.0.0.0到191.255.255.255 ● C类地址由前三段的网络地址和最后一段的主机地址组成范围是192.0.0.0到223.255.255.255 另外还有一个回送地址127.0.0.1指本机地址该地址一般用来测试使用例如ping 127.0.0.1来测试本机TCP/IP是否正常。 通过IP地址可以连接到指定计算机但如果想访问目标计算机中的某个应用程序还需要指定端口号。在计算机中不同的应用程序是通过端口号区分的。端口号是用两个字节16位的二进制数表示的它的取值范围是0~65535其中0~1023之间的端口号由操作系统的网络服务所占用用户的普通应用程序需要使用1024以上的端口号从而避免操作系统服务端口号被其他应用或服务所占用。 接下来通过一个图例描述IP地址和端口号的作用。 9.1.2 InetAddress 在Java中提供了一个与IP地址相关的InetAddress类该类用于封装一个IP地址并提供了一系列与IP地址相关的方法InetAddress类的一些常用方法如下表。 方法声明功能描述InetAddress getByName(String host)参数host表示指定的主机该方法用于在给定主机名的情况下确定主机的 IP 地址InetAddress getLocalHost()创建一个表示本地主机的InetAddress对象String getHostName()得到IP地址的主机名如果是本机则是计算机名不是本机则是主机名如果没有域名则是IP地址Boolean isReachable(int timeout)判断指定的时间内地址是否可以到达String getHostAddress()得到字符串格式的原始 IP 地址 上表列举了InetAddress的五个常用方法。其中前两个方法用于获得该类的实例对象第一个方法用于获得表示指定主机的InetAddress对象第二个方法用于获得表示本地的InetAddress对象。通过InetAddress对象便可获取指定主机名IP地址等。 接下来通过一个案例来演示InetAddress常用方法的使用。 1 import java.net.InetAddress; 2 public class Example01 { 3 public static void main(String[] args) throws Exception { 4 InetAddress localAddress InetAddress.getLocalHost(); 5 InetAddress remoteAddress InetAddress. getByName(www.itcast.cn); 6 System.out.println(本机的IP地址 localAddress.getHostAddress()); 7 System.out.println(itcast的IP地址 remoteAddress.getHostAddress()); 8 System.out.println(3秒是否可达 remoteAddress.isReachable(3000)); 9 System.out.println(itcast的主机名为 remoteAddress.getHostName()); 10 } 11 }上述代码中第4行代码获取本机的IP地址并打印第5~6行代码获取主机名为传智教育【官网】-好口碑IT职业教育,好口碑IT培训机构一样的教育不一样的品质地址第7行代码获取itcast的主机地址。第8行代码判断3秒是否可到达主机。第9行代码用于获取itcast的主机名。 9.1.3 UDP与TCP协议 协议是定义的通信规则一般有TCP协议和UDP协议。通过TCP/IP结构我们知道传输层的两个重要的高级协议分别是UDP和TCP其中UDP是User Datagram Protocol的简称称为用户数据报协议TCP是Transmission Control Protocol的简称称为传输控制协议。 UDP是无连接通信协议即在数据传输时数据的发送端和接收端不建立逻辑连接。简单来说当一台计算机向另外一台计算机发送数据时发送端不会确认接收端是否存在就会发出数据同样接收端在收到数据时也不会向发送端反馈是否收到数据。由于使用UDP协议消耗资源小通信效率高所以通常都会用于音频、视频和普通数据的传输例如视频会议使用UDP协议因为这种情况即使偶尔丢失一两个数据包也不会对接收结果产生太大影响。但是在使用UDP协议传送数据时由于UDP的面向无连接性不能保证数据的完整性因此在传输重要数据时不建议使用UDP协议。 UDP的交互过程如下图。 TCP协议是面向连接的通信协议即在传输数据前先在发送端和接收端建立逻辑连接然后再传输数据它提供了两台计算机之间可靠无差错的数据传输。在TCP连接中必须要明确客户端与服务器端由客户端向服务器端发出连接请求每次连接的创建都需要经过“三次握手”。第一次握手客户端向服务器端发出连接请求等待服务器确认第二次握手服务器端向客户端回送一个响应通知客户端收到了连接请求第三次握手客户端再次向服务器端发送确认信息确认连接。 TCP连接的整个交互过程如下图。 由于TCP协议的面向连接特性它可以保证传输数据的安全性是一个被广泛采用的协议。例如在下载文件时如果数据接收不完整将会导致文件数据丢失而不能被打开因此下载文件时必须采用TCP协议。 9.2 UDP通信 前面介绍了UDP是一种面向无连接的协议因此在通信时发送端和接收端不用建立连接。UDP通信的过程就像是货运公司在两个码头间发送货物一样在码头发送和接收货物时都需要使用集装箱来装载货物。UDP通信也是一样发送和接收的数据也需要使用“集装箱”进行打包为此Java提供了一个DatagramPacket类。然而运输货物只有“集装箱”是不够的还需要有“码头”。同理在程序中要实现通信只有DatagramPacket数据包也是不行的它也需要一个“码头”。为此Java还提供了一个DatagramSocket类。 通过DatagramPacket类和DatagramSocket类发送数据的过程如下图。 9.2.1 DatagramPacket DatagramPacket类用于封装UDP通信中发送或者接收的数据。想要创建一个DatagramPacket对象首先需要了解一下它的构造方法。在创建发送端和接收端的DatagramPacket对象时使用的构造方法有所不同接收端的构造方法只需要接收一个字节数组来存放接收到的数据而发送端的构造方法不但要接收存放了发送数据的字节数组还需要指定发送端IP地址和端口号。 DatagramPacket类用于封装UDP通信中发送或者接收的数据。想要创建一个DatagramPacket对象 1DatagramPacket(byte[] buf,int length) 使用该构造方法在创建DatagramPacket对象时指定了封装数据的字节数组和数据的大小没有指定IP地址和端口号。很明显这样的对象只能用于接收端不能用于发送端。因为发送端一定要明确指出数据的目的地(IP地址和端口号)而接收端不需要明确知道数据的来源只需要接收到数据即可。 2DatagramPacket(byte[] buf,int length,InetAddress addr,int port) 使用该构造方法在创建DatagramPacket对象时不仅指定了封装数据的字节数组和数据的大小还指定了数据包的目标IP地址addr和端口号port。该对象通常用于发送端因为在发送数据时必须指定接收端的IP地址和端口号就好像发送货物的集装箱上面必须标明接收人的地址一样。 3DatagramPacket(byte[] buf,int offset,int length) 该构造方法与第一个构造方法类似同样用于接收端只不过在第一个构造方法的基础上增加了一个offset参数该参数用于指定接收到的数据在放入buf缓冲数组时是从offset处开始的。 4DatagramPacket(byte[] buf,int offset,int length,InetAddress addr,int port) 该构造方法与第二个构造方法类似同样用于发送端只不过在第二个构造方法的基础上增加了一个offset参数该参数用于指定一个数组中发送数据的偏移量为offset即从offset位置开始发送数据。 上面已经讲解了DatagramPacket的构造方法接下来对DatagramPacket类中的常用方法进行详细的讲解。 方法声明功能描述InetAddress getAddress()该方法用于返回发送端或者接收端的IP地址如果是发送端的DatagramPacket对象就返回接收端的IP地址反之就返回发送端的IP地址int getPort()该方法用于返回发送端或者接收端的端口号如果是发送端的DatagramPacket对象就返回接收端的端口号反之就返回发送端的端口号byte[] getData()该方法用于返回将要接收或者将要发送的数据如果是发送端的DatagramPacket对象就返回将要发送的数据反之就返回接收到的数据int getLength()该方法用于返回接收或者将要发送数据的长度如果是发送端的DatagramPacket对象就返回将要发送的数据长度反之就返回接收到数据的长度 9.2.2 DatagramSocket 使用DatagramSocket类的实例对象就可以发送和接收DatagramPacket数据包在创建发送端和接收端的DatagramSocket对象时使用的构造方法也有所不同下面对DatagramSocket类中常用的构造方法进行讲解。 1DatagramSocket() 该构造方法用于创建发送端的DatagramSocket对象在创建DatagramSocket对象时并没有指定端口号此时系统会分配一个没有被其他网络程序所使用的端口号。 2DatagramSocket(int port) 该构造方法既可用于创建接收端的DatagramSocket对象又可以创建发送端的DatagramSocket对象在创建接收端的DatagramSocket对象时必须要指定一个端口号这样就可以监听指定的端口。 3DatagramSocket(int port,InetAddress addr) 使用该构造方法在创建DatagramSocket对象时不仅指定了端口号还指定了相关的IP地址。该对象的使用适用于计算机上有多块网卡的情况在使用时可以明确规定数据通过哪块网卡向外发送和接收哪块网卡的数据。由于计算机中针对不同的网卡会分配不同的IP因此在创建DatagramSocket对象时需要通过指定IP地址确定使用哪块网卡进行通信。 上面我们讲解了DatagramSocket的常用构造方法接下来对DatagramSocket类中的常用方法进行详细的讲解。 方法声明功能描述void receive(DatagramPacket p)该方法用于将接收到的数据填充到DatagramPacket数据包中在接收到数据之前会一直处于阻塞状态只有当接收到数据包时该方法才会返回void send(DatagramPacket p)该方法用于发送DatagramPacket数据包发送的数据包中包含将要发送的数据、数据的长度、远程主机的IP地址和端口号void close()关闭当前的Socket通知驱动程序释放为这个Socket保留的资源 9.2.3 UDP网络程序 前面两个小节讲解了DatagramPacket和DatagramSocket的相关知识接下来通过一个案例来学习一下它们在程序中的具体用法。要实现UDP通信需要创建一个发送端程序和一个接收端程序。很明显在通信时只有接收端程序先运行才能避免发送端发送数据时找不到接收端而造成数据丢失的问题。因此首先需要完成接收端程序的编写。接收端程序如下。 package com.javase.text9;import java.net.*; // 接收端程序 public class Receiver {public static void main(String[] args) throws Exception {byte[] buf new byte[1024]; // 创建一个字节数组用于接收数据// 定义一个DatagramSocket对象监听的端口号为8954DatagramSocket ds new DatagramSocket(8954);// 定义一个DatagramPacket对象用于接收数据DatagramPacket dp new DatagramPacket(buf, buf.length);System.out.println(等待接收数据);ds.receive(dp); // 等待接收数据如果没有数据则会阻塞// 调用DatagramPacket的方法获得接收到的信息//包括数据的内容、长度、发送的IP地址和端口号String str new String(dp.getData(), 0, dp.getLength()) from dp.getAddress().getHostAddress() : dp.getPort();System.out.println(str); // 打印接收到的信息ds.close();// 释放资源} } 创建了一个接收端程序用来接收数据。其中第6行代码创建了一个DatagramSocket对象并指定其监听的端口号为8954这样发送端就能通过这个端口号与接收端程序进行通信。第9行代码在创建DatagramPacket对象时传入一个大小为1024个字节的数组用来接收数据第11行代码调用DatagramPacket对象的receive()方法接收到数据以后数据会填充到DatagramPacket中第14~15行代码是通过DatagramPacket的相关方法可以获取接收到的数据的内容、长度、发送的IP地址和端口号等信息第17行代码是释放资源。 从运行结果可以看到程序运行后程序一直处于停滞状态这是因为DatagramSocket的receive()方法在运行时会发生阻塞只有接收到发送端程序发送的数据时该方法才会结束这种阻塞状态程序才能继续向下执行。 实现了接收端程序之后接下来还需要编写一个发送端的程序。 package com.javase.text9;import java.net.*; //发送端程序 public class Sender {public static void main(String[] args) throws Exception {// 创建一个DatagramSocket对象DatagramSocket ds new DatagramSocket(3000);String str hello world; // 要发送的数据byte[] arr str.getBytes(); //将定义的字符串转为字节数组//创建一个要发送的数据包数据包包括发送的数据//数据的长度接收端的IP地址以及端口号DatagramPacket dp new DatagramPacket(arr, arr.length,InetAddress.getByName(localhost), 8954);System.out.println(发送信息);ds.send(dp); // 发送数据ds.close(); // 释放资源} } 上述代码中创建了一个发送端程序用来发送数据。在创建DatagramPacket对象时需要指定目标IP地址和端口号而且端口号必须要和接收端指定的端口号一致这样调用DatagramSocket的send()方法才能将数据发送到对应的接收端。 在接收端程序阻塞的状态下运行发送端程序接收端程序就会收到发送端发送的数据而结束阻塞状态并打印接收的数据。 在创建发送端的DatagramSocket对象时可以不指定端口号而发送端程序中指定端口号目的就是为了每次运行时接收端的getPort()方法的返回值都是一致的否则发送端的端口号由系统自动分配接收端的getPort()方法的返回值会每次都不同。 M脚下留心 UDP程序所使用的端口号被占用时运行异常 需要注意的是运行接收端程序有时会出现一种异常如下图。 上图所示异常是因为在一台计算机中一个端口号上只能运行一个程序而我们编写的UDP程序所使用的端口号已经被其他的程序占用。遇到这种情况时可以在命令行窗口输入“netstat”命令来查看当前计算机端口占用情况netstat命令运行结果如右图。 上图显示了所有正在运行的应用程序及它们所占用的端口号。想要解决端口号占用的问题只需关掉占用端口号的应用程序或者使用一个未被占用的端口号重新运行程序即可。 9.2.4 多线程的UDP网络程序 在上一节中分别实现了发送端程序和接收端程序当接收端程序阻塞的状态下运行发送端程序接收端程序就会收到发送端发送的数据而结束阻塞状态完成程序运行。实际上发送端可以无限发送数据接收端也可以一直接收数据例如聊天程序发送端可以一直发消息接收端也可以一直接收消息因此发送端和客户端都是多线程的。 接下来通过一个案例演示使用UDP通信方式实现多线程的UDP网络程序。 package com.javase.text9;import java.io.IOException; import java.net.*; import java.util.Scanner; public class Example04 {public static void main(String[] args) {new Receive().start();new Send().start();} } class Receive extends Thread {public void run() {try {//创建socket相当于创建码头DatagramSocket socket new DatagramSocket(6666);//创建packet相当于创建集装箱DatagramPacket packet new DatagramPacket(new byte[1024], 1024);while(true) {socket.receive(packet);//接收货物byte[] arr packet.getData();int len packet.getLength();String ip packet.getAddress().getHostAddress();System.out.println(ip : new String(arr,0,len));}} catch (IOException e) {e.printStackTrace();}} } class Send extends Thread {public void run() {try {//创建socket相当于创建码头DatagramSocket socket new DatagramSocket();Scanner sc new Scanner(System.in);while(true) {String str sc.nextLine();if(quit.equals(str))break;DatagramPacket packet new DatagramPacket(str.getBytes(),str.getBytes().length, InetAddress.getByName(127.0.0.1), 6666);socket.send(packet);//发货}socket.close();} catch (IOException e) {e.printStackTrace();}} } 上述代码中第10~28行代码使用多线程的方法创建了一个接收端程序第17~23行代码通过在接收端的while循环中调用receive()方法不停地接收发送端发送的请求当与发送端建立连接后就会开启一个新的线程该线程会去处理发送端发送的数据而主线程仍处于继续等待状态第29~49行代码使用多线程的方法创建的一个发送端程序第35~43行代码通过在发送端的while循环中调用的send()方法不停的发送数据。 【案例9-1】 模拟微信聊天 如今微信已经成为人们生活中必不可少的一款社交软件。本案例要求编写一个程序模拟微信聊天功能。在实现案例时要求使用多线程与UDP通信完成消息的发送和接收。 1第一要知道用什么技术实现通过上述任务描述可知此任务是使用多线程与UDP通信相关知识实现的。要实现图中的聊天窗口界面。首先需要定义一个实现微信聊天功能的类类中需要定义访问微信聊天的输出语句从而获取输入的发送端端口号、接收端端口号以及实现发送和接收功能的方法。 2实现发送数据的功能。该功能通过一个实现了Runnable接口的类实现类中需要定义获取发送数据的端口号并在实现run()的方法中编写发送数据的方法。 3实现接收数据的功能。该功能通过一个实现了Runnable接口的类实现类中需要定义获取接收数据的端口号并在实现run()的方法中编写显示接收到的数据的方法。 4创建完所有的类与方法后运行两次程序同时开启两个窗口来实现聊天功能。 1 import java.util.Scanner;2 public class Room {3 public static void main(String[] args) {4 System.out.println(微信聊天欢迎您!);5 Scanner sc new Scanner(System.in);6 System.out.print(请输入您的微信号登录);7 int sendPort sc.nextInt();8 System.out.print(请输入您要发送消息的微信号);9 int receivePort sc.nextInt();10 System.out.println(微信聊天系统启动); 11 //发送操作12 new Thread(new SendTask(sendPort), 发送端任务).start();13 //接收操作14 new Thread(new ReceiveTask(receivePort), 接收端任务).start();15 }16 }1 import java.net.DatagramPacket;2 import java.net.DatagramSocket;3 import java.net.InetAddress;4 import java.util.Scanner;5 public class SendTask implements Runnable {6 private int sendPort; // 发数据的端口号7 // 构造方法8 public SendTask(int sendPort) {9 this.sendPort sendPort;10 }11 Override12 public void run() {13 try {14 // 1. 创建DatagramSocket对象15 DatagramSocket ds new DatagramSocket();16 // 2.输入要发送的数据17 Scanner sc new Scanner(System.in);18 while (true) {19 String data sc.nextLine();// 获取键盘输入的数据20 // 3.封装数据到 DatagramPacket对象中21 byte[] buf data.getBytes();22 DatagramPacket dp new DatagramPacket(buf, buf.length,23 InetAddress.getByName(127.0.0.255),sendPort);24 // 4.发送数据25 ds.send(dp);26 }27 } catch (Exception e) {28 e.printStackTrace();29 }30 }31 } 1 import java.net.DatagramPacket;2 import java.net.DatagramSocket;3 public class ReceiveTask implements Runnable{4 private int receivePort;// 接收数据的端口号5 public ReceiveTask(int receivePort) {6 this.receivePort receivePort;7 }8 Override9 public void run() {10 try {11 // 1.DatagramSocket对象12 DatagramSocket ds new DatagramSocket(receivePort);13 // 2.创建DatagramPacket对象14 byte[] buf new byte[1024];15 DatagramPacket dp new DatagramPacket(buf, buf.length);16 // 3.接收数据17 while (true) {18 ds.receive(dp);19 // 4.显示接收到的数据20 String str new String(dp.getData(), 0, 21 dp.getLength());22 System.out.println(收到 23 dp.getAddress().getHostAddress()24 --发送的数据-- str);25 }26 } catch (Exception e) {27 e.printStackTrace();28 }29 }30 }9.3 TCP通信 TCP通信同UDP通信一样也能实现两台计算机之间的通信但TCP通信的两端需要创建socket对象。UDP通信与TCP通信的区别在于UDP中只有发送端和接收端不区分客户端与服务器端计算机之间可以任意地发送数据而TCP通信是严格区分客户端与服务器端的在通信时必须先由客户端去连接服务器端才能实现通信服务器端不可以主动连接客户端并且服务器端程序需要事先启动等待客户端的连接。 Java提供了两个用于实现TCP程序的类一个是ServerSocket类用于表示服务器端一个是Socket类用于表示客户端。通信时首先要创建代表服务器端的ServerSocket对象创建该对象相当于开启一个服务此服务会等待客户端的连接然后创建代表客户端的Socket对象使用该对象向服务器端发出连接请求服务器端响应请求后两者才建立连接开始通信。 整个通信过程如下图。 9.3.1 ServerSocket 通过前面的学习可知在开发TCP程序时首先需要创建服务器端程序。java.net包提供了一个ServerSocket类该类的实例对象可以实现一个服务器端的程序。通过查阅API文档可知ServerSocket类提供了多种构造方法。 1ServerSocket() ServerSocket有一个不带参数的默认构造方法。通过该方法创建的ServerSocket对象不与任何端口绑定这样的ServerSocket对象创建的服务器端没有监听任何端口不能直接使用还需要继续调用bind(SocketAddress endpoint)方法将其绑定到指定的端口号上才可以正常使用。 2ServerSocket(int port) 使用该构造方法在创建ServerSocket对象时可以将其绑定到一个指定的端口号上参数port就是端口号。端口号可以指定为0此时系统就会分配一个还没有被其他网络程序所使用的端口号。由于客户端需要根据指定的端口号来访问服务器端程序因此端口号随机分配的情况并不常用通常都会让服务器端程序监听一个指定的端口号。 3ServerSocket(int port, int backlog) 该构造方法就是在第二个构造方法的基础上增加了一个backlog参数。该参数用于指定在服务器忙时可以与之保持连接请求的等待客户数量如果没有指定这个参数默认为50。 4ServerSocket(int port, int backlog, InetAddress bindAddr) 该构造方法就是在第三个构造方法的基础上增加了一个bindAddr参数该参数用于指定相关的IP地址。该构造方法的使用适用于计算机上有多块网卡和多个IP的情况使用时可以明确规定ServerSocket在哪块网卡或IP地址上等待客户的连接请求。显然对于一般只有一块网卡的情况就不用专门的指定了。 除了构造方法ServerSocket还提供了其他常用方法如下表。 方法声明功能描述Socket accept()该方法用于等待客户端的连接在客户端连接之前会一直处于阻塞状态如果有客户端连接就会返回一个与之对应的Socket对象InetAddress getInetAddress()该方法用于返回一个InetAddress对象该对象中封装了ServerSocket绑定的IP地址boolean isClosed()该方法用于判断ServerSocket对象是否为关闭状态如果是关闭状态则返回true反之则返回falsevoid bind(SocketAddress endpoint)该方法用于将ServerSocket对象绑定到指定的IP地址和端口号其中参数endpoint 封装了IP 地址和端口号 ServerSocket对象负责监听某台计算机的某个端口号在创建ServerSocket对象后需要继续调用该对象的accept()方法接收来自客户端的请求。当执行了accept()方法之后服务器端程序会发生阻塞直到客户端发出连接请求时accept()方法才会返回一个Socket对象用于和客户端实现通信程序才能继续向下执行。 9.3.2 Socket ServerSocket对象可以实现服务器端程序但只实现服务器端程序还不能完成通信此时还需要一个客户端程序与之交互为此Java提供了一个Socket类用于实现TCP客户端程序。通过查阅API文档可知Socket类同样提供了多种构造方法。 1Socket() 使用该构造方法在创建Socket对象时并没有指定IP地址和端口号也就意味着只创建了客户端对象并没有去连接任何服务器。通过该构造方法创建对象后还需调用connect(SocketAddress endpoint)方法才能完成与指定服务器端的连接其中参数endpoint用于封装IP地址和端口号。 2Socket(String host, int port) 使用该构造方法在创建Socket对象时会根据参数去连接在指定地址和端口上运行的服务器程序其中参数host接收的是一个字符串类型的IP地址。 3Socket(InetAddress address, int port) 该构造方法在使用上与第二个构造方法类似参数address用于接收一个InetAddress类型的对象该对象用于封装一个IP地址。 除了构造方法Socket还提供了很多其他方法如下表。 方法声明功能描述int getPort()该方法返回一个int类型对象该对象是Socket对象与服务器端连接的端口号InetAddress getLocalAddress()该方法用于获取Socket对象绑定的本地IP地址并将IP地址封装成InetAddress类型的对象返回void close()该方法用于关闭Socket连接结束本次通信。在关闭Socket之前应将与Socket相关的所有的输入输出流全部关闭这是因为一个良好的程序应该在执行完毕时释放所有的资源InputStream getInputStream()该方法返回一个InputStream类型的输入流对象如果该对象是由服务器端的Socket返回就用于读取客户端发送的数据反之用于读取服务器端发送的数据OutputStream getOutputStream()该方法返回一个OutputStream类型的输出流对象如果该对象是由服务器端的Socket返回就用于向客户端发送数据反之用于向服务器端发送数据 接下来通过一张图描述服务器端和客户端的数据传输。 9.3.3 简单的TCP网络程序 接下来通过一个TCP通信的案例来进一步学习ServerSocket、Socket类的用法。要实现TCP通信需要创建一个服务器端程序和一个客户端程序为了保证数据传输的安全性首先需要实现服务器端程序。服务器端程序实现如下。 package com.javase.text9;import java.io.*; import java.net.*; public class Server {public static void main(String[] args) throws Exception {new TCPServer().listen(); // 创建TCPServer对象并调用listen()方法} } // TCP服务器端 class TCPServer {private static final int PORT 7788; // 定义一个端口号public void listen() throws Exception { // 定义一个listen()方法抛出异常ServerSocket serverSocket new ServerSocket(PORT);// 调用ServerSocket的accept()方法接收数据Socket client serverSocket.accept();OutputStream os client.getOutputStream();// 获取客户端的输出流System.out.println(开始与客户端交互数据);// 当客户端连接到服务器端时向客户端输出数据os.write((传智播客欢迎你).getBytes());Thread.sleep(5000);// 模拟执行其他功能占用的时间System.out.println(结束与客户端交互数据);os.close();client.close();} } 上述代码中第9~24行代码封装了一个TCP服务端的方法第12行代码创建ServerSocket对象时指定了端口号7788第14代码调用ServerSocket对象的accept()方法用于接收数据第15行代码使用OutputStream获取客户端的输出流第19行代码使用线程的sleep()方法使线程休眠5000毫秒用于模拟执行其他功能占用的时间最后在第21~22行代码中分别使用OutputStream与Socket的close()方法关闭了OutputStream与Socket。 从运行结果可以看出控制台中的光标一直在闪动这是因为accept()方法发生阻塞程序暂时停止运行直到有客户端来访问时才会结束这种阻塞状态。这时该方法会返回一个Socket类型的对象用于表示客户端通过该对象获取与客户端关联的输出流并向客户端发送信息同时执行Thread.sleep(5000)语句模拟服务器执行其他功能占用的时间。最后调用Socket对象的close()方法将通信结束。 package com.javase.text9;import java.io.*; import java.net.*; public class Client {public static void main(String[] args) throws Exception {new TCPClient().connect();// 创建TCPClient对象并调用connect()方法} } //TCP客户端 class TCPClient {private static final int PORT 7788; // 服务器端的端口号public void connect() throws Exception {//创建一个Socket并连接到给出地址和端口号的计算机Socket client new Socket(InetAddress.getLocalHost(), PORT);InputStream is client.getInputStream(); // 得到接收数据的流byte[] buf new byte[1024]; // 定义1024个字节数组的缓冲区int len is.read(buf); // 将数据读到缓冲区中System.out.println(new String(buf, 0, len));// 将缓冲区中的数据输出client.close(); // 关闭Socket对象,释放资源} } 上述代码中第9~20行代码封装了一个TCP客户端的方法第13行代码创建了一个Socket并连接到给出地址给端口号的计算机第14行代码使用InputStream接收得到的数据流第15行代码定义1024个字节数组的缓冲区第16行代码将InputStream接收到的数据读到缓冲区中最后在第18行代码中使用Socket的close()方法关闭Socket。 在客户端创建的Socket对象与服务器端建立连接后通过Socket对象获得输入流读取服务器端发来的数据并打印出如上图所示的结果。 同时服务器端程序会结束阻塞状态并在控制台中打印出“开始与客户端交互数据”然后向客户端发出数据“传智播客欢迎你”在休眠5秒钟后会在控制台打印出“结束与客户端交互数据”此时本次通信才结束。 9.3.4 多线程的TCP网络程序 实际上很多服务器端程序都是允许被多个应用程序访问的例如门户网站可以被多个用户同时访问因此服务器都是多线程的。下面就通过一个图例来表示多个用户访问同一个服务器。 在上图中服务器端为每个客户端创建一个对应的Socket并且开启一个新的线程使两个Socket建立专线进行通信。接下来根据上图所示的通信方式对9.3.3节的服务器端程序进行改进。 import java.io.*; import java.net.*; public class Server {public static void main(String[] args) throws Exception {new TCPServer().listen(); // 创建TCPServer对象并调用listen()方法} } // TCP服务器端 class TCPServer {private static final int PORT 7788; // 定义一个静态常量作为端口号public void listen() throws Exception {// 创建ServerSocket对象监听指定的端口ServerSocket serverSocket new ServerSocket(PORT); // 使用while循环不停的接收客户端发送的请求while (true) {// 调用ServerSocket的accept()方法与客户端建立连接final Socket client serverSocket.accept();// 下面的代码用来开启一个新的线程new Thread() { public void run() {OutputStream os; // 定义一个输出流对象try {os client.getOutputStream(); // 获取客户端的输出流System.out.println(开始与客户端交互数据);os.write((中国人民欢迎你).getBytes());Thread.sleep(5000); // 使线程休眠5000毫秒System.out.println(结束与客户端交互数据);os.close(); // 关闭输出流client.close(); // 关闭Socket对象} catch (Exception e) {e.printStackTrace();}};}.start();}} }在上述代码中第9~37行代码使用多线程的方式创建了一个服务器端程序。第15~35行代码通过在while循环中调用accept()方法不停地接收客户端发送的请求当与客户端建立连接后就会开启一个新的线程该线程会去处理客户端发送的数据而主线程仍处于继续等待状态。 为了验证服务器端程序是否实现了多线程首先运行服务器端程序之后运行三个客户端程序当运行第一个客户端程序时服务器端马上就进行数据处理打印出“开始与客户端交互数据”再运行第二、和第三个客户端程序会发现服务器端也立刻做出回应三个客户端会话结束后分别打印各自结束信息如下图所示。 【案例9-2】 字符串反转 在使用软件或浏览网页时我们总会查询一些数据查询数据的过程其实就是客户端与服务器交互的过程。我们客户端将查询信息发送给服务器服务器接收到查询消息之后进行处理将查询结果返回给我们客户端。本案例要求编写一个程序模拟客户端与服务器的交互客户端向服务器传递一个字符串(键盘录入) 服务器将字符串反转后写回客户端再次接读取到的是反转后的字符串。本案例要求使用多线程与TCP通信相关知识完成数据交互。 1根据任务描述可以知道该程序用TCP通信技术实现所以第一条就是定义客户端键盘录入数据定义Scanner来实现然后创建客户端指定IP地址和端口号之后获取输出流与输入流最后将字符串写到服务器并将反转后的结果读出来打印在控制台。 2实现服务端的代码编写首先创建服务端绑定客户端的端口号并用Server的accept()方法接受客户端的请求。 3服务端定义run()方法实现之后获取输入输出流将客户端发送过来的数据读取出来并采用链式编程的思想将字符串反转后返回到客户端。 1 import java.io.BufferedReader;2 import java.io.IOException;3 import java.io.InputStreamReader;4 import java.io.PrintStream;5 import java.net.Socket;6 import java.net.UnknownHostException;7 import java.util.Scanner;8 public class client {9 public static void main(String[] args) throws UnknownHostException, 10 IOException {11 //创建键盘录如对象12 Scanner sc new Scanner(System.in); 13 //创建客户端,指定ip地址和端口号 14 Socket socket new Socket(127.0.0.1, 54321); 15 BufferedReader br new BufferedReader(new 16 InputStreamReader(socket.getInputStream())); //获取输入流17 //获取输出流18 PrintStream ps new PrintStream(socket.getOutputStream());19 //将字符串写到服务器去20 ps.println(sc.nextLine()); 21 System.out.println(br.readLine()); //将反转后的结果读出来 22 socket.close();23 }24 }1 import java.io.BufferedReader;2 import java.io.IOException;3 import java.io.InputStreamReader;4 import java.io.PrintStream;5 import java.net.ServerSocket;6 import java.net.Socket;7 public class server {8 public static void main(String[] args) throws IOException {9 ServerSocket server new ServerSocket(54321);10 System.out.println(服务器启动,绑定54321端口);11 while(true) {12 final Socket socket server.accept(); //接受客户端的请求13 new Thread() { //开启一条线程14 public void run() {15 try {16 BufferedReader br new BufferedReader(new 17 InputStreamReader18 socket.getInputStream())); //获取输入流19 PrintStream ps new PrintStream20 (socket.getOutputStream());//获取输出流21 //将客户端写过来的数据读取出来22 String line br.readLine()23 line new StringBuilder(line).24 reverse().toString(); //链式编程25 ps.println(line); //反转后写回去26 socket.close();27 } catch (IOException e) { 28 e.printStackTrace();29 }30 }31 }.start();32 }33 }34 }【案例9-3】 上传文件 在日常工作生活中我们总会将工作成果或生活照片等上传到某一个软件其实这个上传过程就是将数据保存到了软件服务端。本案例要求编写一个程序模拟向服务端上传文件在本地机器中输入一个路径将该路径下的文件上传到服务端D盘中名称为upload的文件夹中。在上传时把客户端的IP地址加上count标识作为上传后文件的名称即IPcount的形式。其中count随着文件的增多而增大如127.0.0.(1).jpg、127.0.0.(2).jpg。本案例要求使用多线程与TCP通信相关知识完成数据上传。 1根据任务描述中使用TCP通信的知识实现文件上传功能可知要实现此功能需要定义一个服务器接收文件的程序和 一个客户端上传文件的程序。 2首先要编写服务器端程序来接收文件。服务器端需要使用ServerSocket对象的accept()方法接收客户端的请求由于一个服务器可能对于多个客户端所以当客户端与服务器端简历连接后服务器需要单独开启一个新的线程来处理与客户端的交互这时需要在服务器端编写开启新线程的方法。在新线程的方法中需要获取客户端的端口号并且使用输入输出流来传输文件到指定的目录中。 3编写客户端的功能代码客户端功能的实现因为是用户自己输入上传文件。所以要定义键盘录入。录入后需要使用Socket类来创建客户对象并通过输入输出流来定义指定的文件。 4最后我们启动程序先启动服务端程序再运行客户端程序来测试上传的结果。 1 import java.io.File;2 import java.io.FileOutputStream;3 import java.io.InputStream;4 import java.io.OutputStream;5 import java.net.ServerSocket;6 import java.net.Socket;7 public class FileServer {8 public static void main(String[] args) throws Exception {9 //创建ServerSocket对象10 ServerSocket serverSocket new ServerSocket(10001); 11 while (true) {12 // 调用accept()方法接收客户端请求得到Socket对象13 Socket s serverSocket.accept();14 // 每当和客户端建立Socket连接后单独开启一个线程处理和客户端的交互15 new Thread(new ServerThread(s)).start();16 }17 }18 }19 class ServerThread implements Runnable {20 // 持有一个Socket类型的属性21 private Socket socket; 22 // 构造方法中把Socket对象作为实参传入23 public ServerThread(Socket socket) { 24 this.socket socket;25 }26 public void run() {27 // 获取客户端的IP地址28 String ip socket.getInetAddress().getHostAddress(); 29 // 上传图片个数30 int count 1; 31 try {32 InputStream in socket.getInputStream();33 // 创建上传图片目录的File对象34 File parentFile new File(D:\\upload\\); 35 // 如果不存在就创建这个目录36 if (!parentFile.exists()) { 37 parentFile.mkdir();38 }39 // 把客户端的IP地址作为上传文件的文件名40 File file new File(parentFile, ip ( count 41 ).jpg);42 while (file.exists()) {43 // 如果文件名存在则把count44 file new File(parentFile, ip ( (count) 45 ).jpg);46 }47 // 创建FileOutputStream对象48 FileOutputStream fos new FileOutputStream(file);49 // 定义一个字节数组50 byte[] buf new byte[1024]; 51 // 定义一个int类型的变量len初始值为052 int len 0; 53 // 循环读取数据54 while ((len in.read(buf)) ! -1) { 55 fos.write(buf, 0, len);56 }57 // 获取服务端的输出流58 OutputStream out socket.getOutputStream();59 // 上传成功后向客户端写出“上传成功”60 out.write(上传成功.getBytes()); 61 // 关闭输出流对象62 fos.close(); 63 // 关闭Socket对象64 socket.close(); 65 } catch (Exception e) {66 throw new RuntimeException(e);67 }68 }1 import java.io.FileInputStream;2 import java.io.InputStream;3 import java.io.OutputStream;4 import java.net.Socket;5 import java.util.Scanner;6 public class FileClient {7 public static void main(String[] args) throws Exception {8 // 创建客户端Socket9 Socket socket new Socket(127.0.0.1, 10001);10 // 获取Socket的输出流对象11 OutputStream out socket.getOutputStream(); 12 // 创建FileInputStream对象13 System.out.println(请输入你要上传文件的路径);14 Scanner sc new Scanner(System.in);15 String upload sc.nextLine();16 if(!upload.isEmpty()){17 FileInputStream fis new FileInputStream(upload);18 // 定义一个字节数组19 byte[] buf new byte[1024];20 // 定义一个int类型的变量len21 int len; 22 // 循环读取数据23 while ((len fis.read(buf)) ! -1) { 24 out.write(buf, 0, len);25 }26 // 关闭客户端输出流27 socket.shutdownOutput();28 // 获取Socket的输入流对象29 InputStream in socket.getInputStream(); 30 // 定义一个字节数组31 byte[] bufMsg new byte[1024];32 // 接收服务端的信息33 int num in.read(bufMsg); 34 String Msg new String(bufMsg, 0, num);35 System.out.println(Msg);36 // 关键输入流对象37 fis.close(); 38 // 关闭Socket对象39 socket.close(); 40 }else {41 System.out.println(对不起请您输入文件路径后再上传);42 }43 }44 }45 }9.4 本章小结 本章讲解了Java网络编程的相关知识。首先简要介绍了网络通信协议的相关知识然后着重介绍了与UDP网络编程相关的DatagramSocket、DatagramPacket类并通过两个的案例实现了UDP通信。最后讲解了TCP网络编程中相关的ServerSocket、Socket类并通过两个案例实现了TCP通信。通过对本章的学习读者能够了解网络编程相关的知识并能够掌握UDP网络程序和TCP网络程序的编写。
http://www.pierceye.com/news/951978/

相关文章:

  • 社区网站推广方案百度直播推广
  • 上海网站seo诊断吉林网站优化
  • 玉田网站建设做重视频网站
  • 发放淘宝优惠券的网站怎么做网站建设理论依据
  • 信用渭南网站建设做网站实例
  • 南通做百度网站的公司哪家好公司网站建站流程
  • 北京微信网站建设费用知识问答网站开发
  • 网站建设的博客做外国网用哪些网站
  • 网站两侧广告口碑营销的案例及分析
  • 有什么手机网站wordpress 编辑器增加翻译按钮
  • 深圳网站建设企怎样做好公司网站
  • 深圳注册投资公司的条件网络优化推广公司
  • 网站流量统计工具有哪些电子商务网络营销是什么
  • asp+access网站开发实例精讲网站建设开发的主要流程
  • 电子商城开发网站建设做网站推广怎么跟客户沟通
  • 个人网站排名欣赏哪个网站可以做笔译兼职
  • 创建一个网站主页wordpress英文博客主题
  • 天津建站模板搭建电子商务网页设计与网站建设论文
  • 网站空间可以自己做服务器网站环境搭建教程
  • 建一个网站素材哪里来长安城乡建设开发有限公司网站
  • 网站内容由什么组成部分组成微信静首页制作代码
  • 精品课程网站开发平台福建省建设厅网站 保证金
  • 网站后台 不能删除文章贵州建设厅网站首页
  • 重庆市园林建设有限公司网站酒店平台网站建设
  • c 网站开发实例教程超级外链工具 增加外链中
  • ip怎么做网站外贸网站建设哪里好
  • 市网站建设网站排名查询alexa
  • 西安建设网站首页网络互联网推广
  • 百度搜索网站显示图片wordpress 工作室
  • 网站页面模板 建设中集团做网站优势