黑马程序员 第四篇 Java 网络编程 (Foundation; completed)
来源:互联网 发布:表示公司的顶级域名 编辑:程序博客网 时间:2024/05/21 14:24
——- android培训、java培训、期待与您交流! ———-
1. 网络编程
1.1 TCP/IP协议
1.2 网络编程模型
网络编程目前有两种主要的模型,分别是C/S结构和B/S结构、
C/S结构是指客户机/服务器结构。所谓C/S结构,指的是在客户端需要安装客户端软件,由客户端软件负责与服务器端的数据通信,将任务合理分配到客户端和服务端实现,降低了网络的负载开销。
B/S结构是指浏览器/服务器结构。客户端只需要安装网页浏览器,不需要安装客户端软件,大部分逻辑事务处理在服务器端完成,客户端浏览器只完成少量的事务处理,减少了客户端的计算机负载,减轻了系统维护与升级的成本和工作量。
在Java这样的跨平台语言出现之后,B/S架构管理软件更是方便,快捷,高效。
1.3 网络传输协议
UDP
UDP 与 TCP 的主要区别在于 UDP 不一定提供可靠的数据传输。事实上,该协议不能保证数据准确无误地到达目的地。UDP 在许多方面非常有效。当某个程序的目标是尽快地传输尽可能多的信息时(其中任意给定数据的重要性相对较低),可使用 UDP。ICQ 短消息使用 UDP 协议发送消息。 许多程序将使用单独的TCP连接和单独的UDP连接。重要的状态信息随可靠的TCP连接发送,而主数据流通过UDP发送。
TCP
TCP的目的是提供可靠的数据传输,并在相互进行通信的设备或服务之间保持一个虚拟连接。TCP在数据包接收无序、丢失或在交付期间被破坏时,负责数据恢复。它通过为其发送的每个数据包提供一个序号来完成此恢复。记住,较低的网络层会将每个数据包视为一个独立的单元,因此,数据包可以沿完全不同的路径发送,即使它们都是同一消息的组成部分。这种路由与网络层处理分段和重新组装数据包的方式非常相似,只是级别更高而已。为确保正确地接收数据,TCP要求在目标计算机成功收到数据时发回一个确认(即 ACK)。如果在某个时限内未收到相应的 ACK,将重新传送数据包。如果网络拥塞,这种重新传送将导致发送的数据包重复。但是,接收计算机可使用数据包的序号来确定它是否为重复数据包,并在必要时丢弃它。
TCP与UDP的选择
如果比较UDP包和TCP包的结构,很明显UDP包不具备TCP包复杂的可靠性与控制机制。与TCP协议相同,UDP的源端口数和目的端口数也都支持一台主机上的多个应用。一个16位的UDP包包含了一个字节长的头部和数据的长度,校验码域使其可以进行整体校验。(许多应用只支持UDP,如:多媒体数据流,不产生任何额外的数据,即使知道有破坏的包也不进行重发。) 很明显,当数据传输的性能必须让位于数据传输的完整性、可控制性和可靠性时,TCP协议是当然的选择。当强调传输性能而不是传输的完整性时,如:音频和多媒体应用,UDP是最好的选择。在数据传输时间很短,以至于此前的连接过程成为整个流量主体的情况下,UDP也是一个好的选择,如:DNS交换。把SNMP建立在UDP上的部分原因是设计者认为当发生网络阻塞时,UDP较低的开销使其有更好的机会去传送管理数据。TCP丰富的功能有时会导致不可预料的性能低下,但是我们相信在不远的将来,TCP可靠的点对点连接将会用于绝大多数的网络应用。
TCP协议和UDP协议特性区别总结:
1. TCP协议在传送数据段的时候要给段标号;UDP协议不 2. TCP协议可靠;UDP协议不可靠 3. TCP协议是面向连接;UDP协议采用无连接 4. TCP协议负载较高,采用虚电路;UDP采用无连接 5. TCP协议的发送方要确认接收方是否收到数据段(3次握手协议) 6. TCP协议采用窗口技术和流控制
本节参考自
http://feinibuke.blog.51cto.com/1724260/340272/
1.4 端口和套接字
2. 基于TCP/IP协议的网络编程
2.1 Socket套接字
Socket 套接字是基于TCP/IP协议的编程接口,用于描述IP地址和端口,是一个通信链的句柄。应用程序通过Socket套接字向网络发送请求或应答网络请求。
Socket有两种主要的操作方式,包括面向连接的和无连接的。
面向连接的Socket操作就像人们打电话,必须先拨号码,建立一个连接,然后再对话。数据包在到达接收端时的顺序与它们出发时的顺序一样,就像一个人在电话中对另外一个人说话一样,每一个字到达另一个端的时候与它发出时的顺序一样。
无连接的Socket操作就像邮递员送信,邮递员只负责把信送出,至于何时发出,最后能不能到达收信人手中不能保证,无连接的Socket操作也一样,负责发出,但不保证数据包的传输质量,数据包到达目的地的顺序可能与发出时顺序不一样。
2.2 ServerSocket类
Java中的网络编程时通过ServerSocket类和Socket类结合使用来完成的。
ServerSocket类是应用在服务器端的类,一般用来监听指定的端口并接受客户端的连接请求。在服务器端,由ServerSocket类负责实现服务器套接字,ServerSocket类位于java.net包中。
ServerSocket类的构造器
public ServerSocket() throws IOExceptionpublic ServerSocket(int port) throws IOExceptionpublic ServerSocket(int port, int backlog) throws IOExceptionpublic ServerSocket(int port, int backlog, InetAddress bindAddr)throws IOException
Tips:
同一台主机上的同一端口号稚嫩而过分配给一个特定的ServerSocket对象,不能两个ServerSocket对象监听同一个端口。端口号的理论范围为0-65535,但前1024个中的大部分已经分配给了特定的应用协议,所以不能选用。
下面代码使用一个ServerSocket类
import java.net.*;public class JavaNet{ public static void main(String[] args) { try { ServerSocket ss = new ServerSocket(9876); } catch(Exception e) { } }}
ServerSocket常用的方法
accept方法
使用该方法接受客户端的连接请求,并将与客户端的连接封装成一个Socket对象返回。此方法为阻塞方法,在没有接受到任何连接请求前调用此方法的线程讲一直阻塞等待,直到接收到连接请求后此方法才返回,调用此方法的线程才继续运行。
除了accept方法外还有一个close方法可以关闭ServerSocket对象。使用getLocalPort方法获取设置的端口号。
2.3 Socket类
Socket类表示套接字。使用Socket时,需要指定待连接服务器的IP地址及端口号。
Socket类的常用构造器
public Socket(String host, int port)throws UnknownHostException, IOExceptionpublic Socket(inetAddress address, int port)throws IOException
使用Socket类的程序
import java.net.*;public class JavaSocket{ public static void main(String[] args) { try { Socket s = new Socket("192.168.1.119", 9876); s.close(); } catch(Exception e) { } }}
Socket类中同样具有一些方法。其中,getPort方法和getLocalPort方法分别是获取连接的远端接口和使用的本地端口。getInputStream方法和getOutputStream方法分别是获取*Socket对象的输入流和输出流*。
Tips
close方法虽然是很简单的,表示关闭Socket对象。但是该方法在程序中是必须有的,这是一个非常好的网络编程习惯。
2.4 网络编程C/S架构实例
C/S构架的网络编程程序是由服务器端和客户端组成的。Java中的网络编程主要是围绕socket来进行的,在服务器端要建立一个ServerSocket开发一个端口,对客户端进行服务,在客户端要建立一个socket通过IP和服务器端开发的端口访问服务器。
一个运行在服务器端的程序
import java.io.*;import java.net.*;import java.util.*;public class JavaNet{ public static void main(String[] args) { int count = 0; try { //创建绑定到9876端口的ServerSocket对象 ServerSocket server = new ServerSocket(9876); System.out.println("服务器对9876端口正在进行监听"); //服务器循环接收客户端的请求,为不同的客户端提供服务 while(true) { //接收客户端的连接请求,若有连接请求返回连接对应的socket对象 Socket sc = server.accpeet(); //获取当前连接的输入流,并使用处理流进行封装 DataInputStream din = newDataInputStream(sc.getInputStream()); //获取当前连接的输出流,并使用处理流进行封装 DataOutputStream dout = new DataOutputStream(sc.getOutputStream()); //打印客户端信息 System.out.println("这是第"+(++count)+"个客户访问"); System.out.println("客户端ip地址: "+ sc.getInetAddress()); System.out.println("本地端口号: "+sc.getLocalPort()); System.out.println("客户端信息: "+din.readUTF()); //向客户端发送回应信息 dout.writeUTF("服务器的时间为: "+(new Date())+"。"); //关闭流 din.close(); dout.close(); //关闭此socket连接 sc.close() } catch(Exception e) { e.printStackTrace(); } }}
import java.io.*;import java.net.*;public class JavaNet2{ public static void main(String[] args) { try { Socket sc = new Socket("192.168.1.119", "9876"); DataInputStream din = new DataInputStream(sc.getInputStream()); DataOutputStream dout = new DataOutputStream(sc.getOutputStream()); dout.writeUTF("Hello"); System.out.println(din.readUTF); //关闭流 din.close(); dout.close(); //关闭此socket连接 sc.close(); } catch(Exception e) { e.printStackTrace(); } }}
——- android培训、java培训、期待与您交流! ———-
- 黑马程序员 第四篇 Java 网络编程 (Foundation; completed)
- 黑马程序员 第二篇 Java 基础 多线程 (Foundation; completed)
- 黑马程序员 第三篇 Java 集合框架 (Foundation; completed)
- 黑马程序员 第五篇 Java I/O (foundation, completed)
- 黑马程序员 第一篇 Java 异常处理 (Foundation; completed)
- 黑马程序员 第六篇 接口 interface (Foundation; completed)
- 黑马程序员 第七篇 继承 (part 1) (Foundation; completed)
- 黑马程序员 第九篇 正则表达式 this. super. (foundation, completed)
- 黑马程序员 第十篇 控制逻辑(foundation, completed)
- 黑马程序员 第八篇 枚举类 反射机制 泛型(继承part 2) (Foundation; completed)
- 【黑马程序员】java-网络编程篇1
- 黑马程序员-java网络编程
- 黑马程序员--java网络编程
- 黑马程序员-java-网络编程
- 黑马程序员 Java网络编程
- 黑马程序员----java网络编程
- 黑马程序员---网络编程【java】
- 黑马程序员 java网络编程
- Hibernate中execute、executeQuery跟executeUpdate之间的区别
- 在服务器上发布Java Web项目
- UVa 489 刽子手游戏
- Java 反射机制 举例
- 分享一些无特征PHP一句话-20150719
- 黑马程序员 第四篇 Java 网络编程 (Foundation; completed)
- BroadcastReceiver
- epoll
- Unity3d 简单计算器(OnGUI)
- IOS - 用户信息默认界面
- activiti工作流(一)
- poj 1274
- java:浅谈java环境变量
- Unity3D之打开Activity与调用JAVA代码传递参数