一、TCP/IP简介
TCP/IP协议族是互联网使用的协议,也可以用在独立的专用网络中。
TCP/IP协议族包括了IP协议、TCP协议和UDP协议。
IP协议使用IP地址来分发报文,但它是尽力而为的服务,报文可能丢失、乱序或者
重复发送。TCP和UDP协议在IP协议基础上增加了端口号,从而在两台主机的应用
程序间建立起透明的连接。
不同的是,TCP协议会对IP层的错误进行修复,它通过握手消息在主机间建立连接,
之后通过在消息中加入序列号来恢复消息中的错误。而UDP只是简单地扩展了IP协议,
使它能够在应用程序之间工作,而不是主机之间。
关于IP地址,一台主机可以有多个网络接口,而一个接口又可以有多个地址。
有些IP地址是有特殊用途的:
A.回环地址:127.0.0.1,总是被分配给一个回环接口,主要用于测试。
B.私有地址:以10、192.168、172.(16-31)开头,用于私有网络。NAT设备转发报文
时,将一个接口中报文的私有地址端口对映射成另一个接口中的公有地址端口对。这
就使一小组主机能够共享一个IP地址对。
C.多播地址:第一个数字在224~239之间。
二、Socket基础
1.地址的获得
public static void main(String[] args) { try { Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); while (interfaces.hasMoreElements()) { NetworkInterface iface = interfaces.nextElement(); System.out.println("Interface: " + iface.getName()); Enumeration<InetAddress> addrList = iface.getInetAddresses(); if (!addrList.hasMoreElements()) System.out.println("No address"); while (addrList.hasMoreElements()) { InetAddress address = addrList.nextElement(); System.out.println("Address: " + address.getHostAddress()); } } } catch (SocketException e) { e.printStackTrace(); } }
2.TCP实例程序
要注意一点,虽然在Client端只用了一个write()方法发送字符串,服务器端也可能从
多个块中接受该信息。即使回馈字符串在服务器返回时存于一个块中,也可能被TCP
协议分割成多个部分。
TCPEchoClientTest.java
public static void main(String[] args) throws IOException { String server = args[0]; byte[] data = args[1].getBytes(); int port = 7; Socket socket = new Socket(server, port); System.out.println("Connected to server..."); InputStream in = socket.getInputStream(); OutputStream out = socket.getOutputStream(); out.write(data); int totalBytesRcvd = 0; int bytesRcvd; while (totalBytesRcvd < data.length) { if ((bytesRcvd = in.read(data, totalBytesRcvd, data.length - totalBytesRcvd)) == -1) throw new SocketException("Connection closed"); totalBytesRcvd += bytesRcvd; } System.out.println("Received: " + new String(data)); socket.close(); }
TCPEchoServerTest.java
private static final int BUFSIZE = 32; public static void main(String[] args) throws IOException { ServerSocket serverSocket = new ServerSocket(7); int recvMsgSize; byte[] receiveBuf = new byte[BUFSIZE]; while (true) { Socket socket = serverSocket.accept(); System.out.println("Handling client " + " from remote " + socket.getRemoteSocketAddress() + " at local " + socket.getLocalSocketAddress()); InputStream in = socket.getInputStream(); OutputStream out = socket.getOutputStream(); while ((recvMsgSize = in.read(receiveBuf)) != -1) { out.write(receiveBuf, 0, recvMsgSize); } socket.close(); } }
注意new Socket时指定的是远端服务器监听的端口号而没有指定本地端口,因此将
采用默认地址和可用的端口号。在我的机器上Client端口是4593,连接到服务器的
端口7。
3.UDP实例程序
为什么使用UDP协议?如果应用程序只交换少量的数据,TCP连接的建立阶段就至少
要传输其两倍的信息量(还有两倍的往返时间)。
UDPEchoClientTest.java
public static void main(String[] args) throws IOException { InetAddress serverAddress = InetAddress.getByName(args[0]); byte[] bytesToSend = args[1].getBytes(); DatagramSocket socket = new DatagramSocket(); socket.setSoTimeout(3000); DatagramPacket sendPacket = new DatagramPacket( bytesToSend, bytesToSend.length, serverAddress, 7); DatagramPacket receivePacket = new DatagramPacket( new byte[bytesToSend.length], bytesToSend.length); // Packets may be lost, so we have to keep trying int tries = 0; boolean receivedResponse = false; do { socket.send(sendPacket); try { socket.receive(receivePacket); if (!receivePacket.getAddress().equals(serverAddress)) throw new IOException("Receive from unknown source"); receivedResponse = true; } catch (IOException e) { tries++; System.out.println("Timeout, try again"); } } while (!receivedResponse && tries < 5); if (receivedResponse) System.out.println("Received: " + new String(receivePacket.getData())); else System.out.println("No response"); socket.close(); }
UDPEchoServerTest.java
private static final int ECHOMAX = 255; public static void main(String[] args) throws IOException { DatagramSocket socket = new DatagramSocket(7); DatagramPacket packet = new DatagramPacket(new byte[ECHOMAX], ECHOMAX); while (true) { socket.receive(packet); System.out.println("Handling client at " + packet.getAddress()); socket.send(packet); packet.setLength(ECHOMAX); } }
通过这个例子与之前TCP的实例进行比较,有如下区别:
A.DatagramSocket在创建时不需要指定目的地址,因为UDP不需要建立连接,每个
数据报文都可以发送或接收于不同的目的地址。
B.如果像TCP一样在read()上阻塞等待,将可能永远阻塞在那里,因为UDP协议只是
简单地扩展了IP协议,UDP报文可能丢失掉。所以一定要设置阻塞等待的超时时间。
C.UDP协议保留了消息的边界信息,每次receive()调用最多只能接收一次send()方法
调用所发送的数据。
D.一个UDP报文DatagramPacket能传输的最大数据是65507字节,超出部分的字节将
自动被丢弃,而且对接收程序也没有任何的提示。因此缓存数组可以设置成65000字节
左右是安全的。
E.如果反复使用同一个DatagramPacket实例调用receive()方法,每次调用前都必须显式
地将消息的内部长度重置为缓存区的实际长度。
本文向大家介绍MongoDB教程之入门基础知识,包括了MongoDB教程之入门基础知识的使用技巧和注意事项,需要的朋友参考一下 一、文档的注意事项: 1. 键值对是有序的,如:{ "name" : "stephen", "genda" : "male" } 不等于 { "genda" : "male", "name" : "stephen" } 2. 文档信息是大小写敏感的,如:{ "name
本文向大家介绍Java套接字(Socket)网络编程入门,包括了Java套接字(Socket)网络编程入门的使用技巧和注意事项,需要的朋友参考一下 网络应用模式主要有: 主机/终端模式:集中计算,集中管理; 客户机/服务器(Client/Server,简称C/S)模式:分布计算,分布管理; 浏览器/服务器模式:利用Internet跨平台。 www(万维网)就是建立在客户机/服务器模式上,以HTML
创建一个易应用程序只需要短短几分钟的时间 - 通过在设计窗口上“绘制”诸如编辑框和按钮等组件来创建用户界面。然后,为窗口和组件设置属性以规定诸如标题、位置、尺寸等的值。最后,编写处理程序将生命真正赋于程序。 组件及事件驱动 组件及其事件驱动是使用易语言在 Windows 环境下编程的基础知识。所谓“组件”,即用作组成用户图形界面的基本成员,譬如:窗口、编辑框、图片框等等。组件按可否容纳其它组件
网络基础 在互联网上之间的通信交流,一般是基于 TCP (Transmission Control Protocol,传输控制协议) 或者 UDP (User Datagram Protocol,用户数据报协议) ,如下图: 编写 Java 应用,我们只需关注于应用层 (application layer),而不用关心 TCP 和 UDP 所在的传输层是如何实现的。java.net 包含了你编程所
Socket 通常也称作"套接字",是支持 TCP/IP 协议的网络通信应用的基本操作单元,可以用来实现网间不同虚拟机或不同计算机之间的通信。使用TCP/IP协议的应用程序通过在客户端和服务器各自创建一个 Socket ,然后通过操作各自的 Socket 就可以完成客户端和服务器的连接以及数据传输的任务了。 Socket 的本质是编程接口( API ),是对 TCP/IP 的封装。使开发者不需要面
本文向大家介绍Java Mybatis框架入门基础教程,包括了Java Mybatis框架入门基础教程的使用技巧和注意事项,需要的朋友参考一下 一、Mybatis介绍 MyBatis是一款一流的支持自定义SQL、存储过程和高级映射的持久化框架。MyBatis几乎消除了所有的JDBC代码,也基本不需要手工去 设置参数和获取检索结果。MyBatis能够使用简单的XML格式或者注解进行来配置,能够映射基