网站建设 中企动力 顺德,济南 制作网站 公司吗,秀色直播app软件大全,网站页面示意图怎么做在现有的网络中#xff0c;网络通讯的方式主要有两种#xff1a;TCP(传输控制协议)方式UDP(用户数据报协议)方式在网络通讯中#xff0c;TCP方式就类似于拨打电话#xff0c;使用该种方式进行网络通讯时#xff0c;需要建立专门的虚拟连接#xff0c;然后进行可靠的数据传…在现有的网络中网络通讯的方式主要有两种TCP(传输控制协议)方式UDP(用户数据报协议)方式在网络通讯中TCP方式就类似于拨打电话使用该种方式进行网络通讯时需要建立专门的虚拟连接然后进行可靠的数据传输如果数据发送失败则客户端会自动重发该数据。而UDP方式就类似于发送短信使用这种方式进行网络通讯时不需要建立专门的虚拟连接传输也不是很可靠如果发送失败则客户端无法获得。这两种传输方式都是实际的网络编程中进行使用重要的数据一般使用TCP方式进行数据传输而大量的非核心数据则都通过UDP方式进行传递在一些程序中甚至结合使用这两种方式进行数据的传递。由于TCP需要建立专用的虚拟连接以及确认传输是否正确所以使用TCP方式的速度稍微慢一些而且传输时产生的数据量要比UDP稍微大一些。无论使用TCP方式还是UDP方式进行网络通讯网络编程都是由客户端和服务器端组成当然B/S结构的编程中只需要实现服务器端即可。所以下面介绍网络编程的步骤时均以C/S结构为基础进行介绍。网络编程技术1、客户端网络编程步骤客户端(Client)是指网络编程中首先发起连接的程序客户端一般实现程序界面和基本逻辑实现在进行实际的客户端编程时无论客户端复杂还是简单以及客户端实现的方式客户端的编程主要由三个步骤实现建立网络连接客户端网络编程的第一步都是建立网络连接。在建立网络连接时需要指定连接到的服务器的IP地址和端口号建立完成以后会形成一条虚拟的连接后续的操作就可以通过该连接实现数据交换了。交换数据连接建立以后就可以通过这个连接交换数据了。交换数据严格按照请求响应模型进行由客户端发送一个请求数据到服务器服务器反馈一个响应数据给客户端如果客户端不发送请求则服务器端就不响应。根据逻辑需要可以多次交换数据但是还是必须遵循请求响应模型。关闭网络连接在数据交换完成以后关闭网络连接释放程序占用的端口、内存等系统资源结束网络编程。在实际实现时步骤2会出现重复在进行代码组织时由于网络编程是比较耗时的操作所以一般开启专门的现场进行网络通讯。2、服务器端网络编程步骤服务器端(Server)是指在网络编程中被动等待连接的程序服务器端一般实现程序的核心逻辑以及数据存储等核心功能。服务器端的编程步骤和客户端不同是由四个步骤实现依次是监听端口服务器端属于被动等待连接所以服务器端启动以后不需要发起连接而只需要监听本地计算机的某个固定端口即可。这个端口就是服务器端开放给客户端的端口服务器端程序运行的本地计算机的IP地址就是服务器端程序的IP地址。获得连接当客户端连接到服务器端时服务器端就可以获得一个连接这个连接包含客户端的信息例如客户端IP地址等等服务器端和客户端也通过该连接进行数据交换。一般在服务器端编程中当获得连接时需要开启专门的线程处理该连接每个连接都由独立的线程实现。交换数据服务器端通过获得的连接进行数据交换。服务器端的数据交换步骤是首先接收客户端发送过来的数据然后进行逻辑处理再把处理以后的结果数据发送给客户端。简单来说就是先接收再发送这个和客户端的数据交换数序不同。其实服务器端获得的连接和客户端连接是一样的只是数据交换的步骤不同。当然服务器端的数据交换也是可以多次进行的。在数据交换完成以后关闭和客户端的连接。关闭连接当服务器程序关闭时需要关闭服务器端通过关闭服务器端使得服务器监听的端口以及占用的内存可以释放出来实现了连接的关闭。TCP方式是需要建立连接的对于服务器端的压力比较大而UDP是不需要建立连接的对于服务器端的压力比较小罢了。Java网络编程技术和网络编程有关的基本API位于java.net包中该包中包含了基本的网络编程实现该包是网络编程的基础。该包中既包含基础的网络编程类也包含封装后的专门处理WEB相关的处理类。InetAddress类该类的功能是代表一个IP地址并且将IP地址和域名相关的操作方法包含在该类的内部。先来个Demopublicstaticvoidmain(String[] args)throwsIOException {try{//使用域名创建对象InetAddress addressInetAddress.getByName(www.163.com);System.out.println(address);//使用ip创建对象InetAddress address2InetAddress.getByName(222.184.115.167);System.out.println(address2);//获得本机地址对象InetAddress address3 InetAddress.getLocalHost();System.out.println(address3);//获得对象中存储的域名System.out.println(域名address3.getHostName());//获得对象中存储的ip地址System.out.println(IP地址address3.getHostAddress());} catch(Exception e) {// TODO: handle exception}}由于该代码中包含一个互联网的网址所以运行该程序时需要联网否则将产生异常。在后续的使用中经常包含需要使用InetAddress对象代表IP地址的构造方法当然该类的使用不是必须的也可以使用字符串来代表IP地址进行实现。TCP编程在Java语言中对于TCP方式的网络编程提供了良好的支持在实际实现时以java.net.Socket类代表客户端连接以java.net.ServerSocket类代表服务器端连接。在进行网络编程时底层网络通讯的细节已经实现了比较高的封装所以在程序员实际编程时只需要指定IP地址和端口号码就可以建立连接了。正是由于这种高度的封装一方面简化了Java语言网络编程的难度另外也使得使用Java语言进行网络编程时无法深入到网络的底层所以使用Java语言进行网络底层系统编程很困难具体点说Java语言无法实现底层的网络嗅探以及获得IP包结构等信息。但是由于Java语言的网络编程比较简单所以还是获得了广泛的使用。在使用TCP方式进行网络编程时需要按照前面介绍的网络编程的步骤进行下面分别介绍一下在Java语言中客户端和服务器端的实现步骤。在客户端网络编程中首先需要建立连接在Java API中以java.net.Socket类的对象代表网络连接所以建立客户端网络连接也就是创建Socket类型的对象该对象代表网络连接// socket1实现的是连接到IP地址是192.168.1.103的计算机的10000号端口Socket socket1 newSocket(192.168.1.103,10000);// socket2实现的是连接到域名是www.sohu.com的计算机的80号端口Socket socket2 newSocket(www.sohu.com,80);底层网络如何实现建立连接对于程序员来说是完全透明的。如果建立连接时本机网络不通或服务器端程序未开启则会抛出异常。连接一旦建立则完成了客户端编程的第一步紧接着的步骤就是按照“请求-响应”模型进行网络数据交换在Java语言中数据传输功能由Java IO实现也就是说只需要从连接中获得输入流和输出流即可然后将需要发送的数据写入连接对象的输出流中在发送完成以后从输入流中读取数据即可。//获得输出流OutputStream outputStream socket1.getOutputStream();//获得输入流InputStream inputStreamsocket1.getInputStream();这里获得的只是最基本的输出流和输入流对象还可以根据前面学习到的IO知识使用流的嵌套将这些获得到的基本流对象转换成需要的装饰流对象从而方便数据的操作。最后当数据交换完成以后关闭网络连接释放网络连接占用的系统端口和内存等资源完成网络操作示例代码如下socket1.close();以上就是最基本的网络编程功能介绍。接下来写个客户端的Demo程序在客户端发送字符串到服务器并将服务器端的反馈显示到控制台数据交换只进行一次当数据交换进行完成以后关闭网络连接程序结束。先来客户端的代码importjava.io.InputStream;importjava.io.OutputStream;importjava.net.Socket;publicclassClient {publicstaticvoidmain(String[] args) {Socket socket null;InputStream is null;OutputStream os null;try{String msg Hello;String ip localhost;intport 9898;// 建立连接socket newSocket(ip, port);// 发送数据os socket.getOutputStream();os.write(msg.getBytes());// 接收数据is socket.getInputStream();byteb[]newbyte[1024];intn is.read(b);System.out.println(newString(b,0,n));} catch(Exception e) {// TODO: handle exceptione.printStackTrace();} finally{try{//关闭连接和流is.close();os.close();socket.close();} catch(Exception e2) {// TODO: handle exceptione2.printStackTrace();}}}}代码中建服务器端的代码publicclassServer {publicstaticvoidmain(String[] args) {ServerSocket serverSocketnull;Socket socketnull;InputStream is null;OutputStream os null;try{serverSocket newServerSocket(9898);socket serverSocket.accept();is socket.getInputStream();byteb[] newbyte[1024];intn is.read(b);System.out.println(客户端发送了newString(b,0,n));os socket.getOutputStream();os.write(接收成功.getBytes());} catch(Exception e) {// TODO: handle exceptione.printStackTrace();}finally{try{is.close();os.close();socket.close();serverSocket.close();} catch(Exception e2) {// TODO: handle exception}}}}先运行服务器端然后运行客户端服务器接收到数据将数据打印出来之后再返回数据到客户端客户端打印出来在该示例代码中建立了一个监听当前计算机9898号端口的服务器端Socket连接然后获得客户端发送过来的连接如果有连接到达时读取连接中发送过来的内容并将发送的内容在控制台进行输出输出完成以后将客户端发送的内容再反馈给客户端。最后关闭流和连接对象结束程序。在服务器端程序编程中由于服务器端实现的是被动等待连接所以服务器端编程的第一个步骤是监听端口也就是监听是否有客户端连接到达。实现服务器端监听的代码为// 该代码实现的功能是监听当前计算机的9898号端口如果在执行该代码时// 10000号端口已经被别的程序占用那么将抛出异常。否则将实现监听。serverSocket newServerSocket(9898);服务器端编程的第二个步骤是获得连接。该步骤的作用是当有客户端连接到达时建立一个和客户端连接对应的Socket连 接对象从而释放客户端连接对于服务器端端口的占用。通过获得连接使得客户端的连接在服务器端获得了保持另外使得服务器端的端口释放出来可以继续等待其它的客户端连接。 实现获得连接的代码是socket serverSocket.accept();该代码实现的功能是获得当前连接到服务器端的客户端连接。需要说明的是accept和前面IO部分介绍的read方法一样都是一个阻塞方法也就是当无连接时该方法将阻塞程序的执行直到连接到达时才执行该行代码。另外获得的连接会在服务器端的该端口注册这样以后就可以通过在服务器端的注册信息直接通信而注册以后服务器端的端口就被释放出来又可以继续接受其它的连接了。连接获得以后后续的编程就和客户端的网络编程类似了这里获得的Socket类型的连接就和客户端的网络连接一样了只是服务器端需要首先读取发送过来的数据然后进行逻辑处理以后再发送给客户端也就是交换数据的顺序和客户端交换数据的步骤刚好相反。这部分的内容和客户端很类似。--------------------------上面这个示例只是演示了网络编程的基本步骤以及各个功能方法的基本使用只是为网络编程打下了一个基础下面将就几个问题来深入介绍网络编程深层次的一些知识。1.如何复用Socket连接拨通一次电话以后多次对话这就是复用客户端连接。建立连接以后将数据交换的逻辑写到一个循环中只要循环不结束则连接就不会被关闭按照这种思路可以改造一下上面的代码让该程序可以在建立连接一次以后发送三次数据当然这里的次数也可以是多次现在看下新的服务器代码和客户端代码importjava.io.InputStream;importjava.io.OutputStream;importjava.net.ServerSocket;importjava.net.Socket;/*** 服务器代码* */publicclassServer {publicstaticvoidmain(String[] args) {ServerSocket serverSocket null;Socket socket null;InputStream is null;OutputStream os null;try{serverSocket newServerSocket(9898);socket serverSocket.accept();is socket.getInputStream();os socket.getOutputStream();byteb[] newbyte[1024];for(inti 0; i 3; i) {intn is.read(b);os.write((客户端发送的内容newString(b,0, n)).getBytes());}} catch(Exception e) {// TODO: handle exceptione.printStackTrace();} finally{try{is.close();os.close();socket.close();serverSocket.close();} catch(Exception e2) {// TODO: handle exception}}}}再看下新的客户端代码importjava.io.InputStream;importjava.io.OutputStream;importjava.net.Socket;/*** 客户端代码* */publicclassClient {publicstaticvoidmain(String[] args) {Socket socket null;InputStream is null;OutputStream os null;try{String msg[] { one,two,three};String ip localhost;intport 9898;// 建立连接socket newSocket(ip, port);// 发送数据os socket.getOutputStream();// 接收数据is socket.getInputStream();byteb[] newbyte[1024];for(inti 0; i os.write(msg[i].getBytes());intn is.read(b);System.out.println(newString(b,0, n));}} catch(Exception e) {// TODO: handle exceptione.printStackTrace();} finally{try{// 关闭连接和流is.close();os.close();socket.close();} catch(Exception e2) {// TODO: handle exceptione2.printStackTrace();}}}}上面的代码虽然比较简单但是通用性比较差。在该程序中比较明显的体现出了“请求-响应”模型也就是在客户端发起连接以后首先发送字符串“First”给服务器端服务器端输出客户端发送的内容“First”然后将客户端发送的内容再反馈给客户端这样客户端也输出服务器反馈“First”这样就完成了客户端和服务器端的一次对话三次会话的过程一样在这个过程中每次都是客户端程序首先发送数据给服务器端服务器接收数据以后将结果反馈给客户端客户端接收到服务器端的反馈从而完成一次通讯过程。2、如何使服务器端支持多个客户端同时工作一个服务器端一般都需要同时为多个客户端提供通讯如果需要同时支持多个客户端则必须使用前面介绍的线程的概念。简单来说也就是当服务器端接收到一个连接时启动一个专门的线程处理和该客户端的通讯。改造之后的服务器代码可以接收多个客户端的数据。在该示例代码中实现了一个while形式的死循环由于accept方法是阻塞方法所以当客户端连接未到达时将阻塞该程序的执行当客户端到达时接收该连接并启动一个新的LogicThread线程处理该连接然后按照循环的执行流程继续等待下一个客户端连接。这样当任何一个客户端连接到达时都开启一个专门的线程处理通过多个线程支持多个客户端同时处理。/*** 支持多客户端的服务器代码* */publicclassServer {publicstaticvoidmain(String[] args) {ServerSocket serverSocket null;Socket socket null;try{serverSocket newServerSocket(9898);while(true) {socket serverSocket.accept();// 启动线程// 实现接收客户端连接然后开启专门的逻辑线程处理该连接// LogicThread类实现对于一个客户端连接的逻辑处理将处理的逻辑放置在该类的run方法中。newLogicThread(socket);}} catch(Exception e) {// TODO: handle exceptione.printStackTrace();} finally{try{socket.close();serverSocket.close();} catch(Exception e2) {// TODO: handle exception}}}staticclassLogicThreadextendsThread {Socket socket null;publicLogicThread(Socket socket) {this.socket socket;start();}Overridepublicvoidrun() {byteb[] newbyte[1024];InputStream is null;OutputStream os null;try{is socket.getInputStream();os socket.getOutputStream();intn is.read(b);os.write((客户端发送的内容newString(b,0, n)).getBytes());} catch(Exception e) {// TODO: handle exceptione.printStackTrace();} finally{try{is.close();os.close();socket.close();} catch(Exception e2) {// TODO: handle exception}}}}}这里的示例还只是基础的服务器端实现在实际的服务器端实现中由于硬件和端口数的限制所以不能无限制的创建线程对象而且频繁的创建线程对象效率也比较低所以程序中都实现了线程池来提高程序的执行效率。这里简单介绍一下线程池的概念线程池(Thread pool)是池技术的一种就是在程序启动时首先把需要个数的线程对象创建好例如创建5000个线程对象然后当客户端连接到达时从池中取出一个已经创建完成的线程对象使用即可。当客户端连接关闭以后将该线程对象重新放入到线程池中供其它的客户端重复使用这样可以提高程序的执行速度优化程序对于内存的占用等。关于基础的TCP方式的网络编程就介绍这么多下面一章介绍UDP方式的网络编程在Java语言中的实现。