一、简单网络知识
1、通信模型
现在通用的网络模型是TCP/ip(Transmission Control PRotocol/Internet Protocol 传输控制协议/因特网互联协议);
其与OSI网络模型的对比如下图:

2、网络通信的三要素
(1)IP地址:用来标识网络上的一台独立的主机。
(2)端口号:用于标识进程的逻辑地址。不同的进程都有不同的端口标识。
端口:要将数据发送到对方指定的应用程序上,为了标识这些应用程序,所以给这些网络应用程序都用数字进行标识。为了方便称呼这些数字,则将这些数字称为端口。(此端口是一个逻辑端口)
(3)传输协议:通讯的规则。例如:TCP、UDP协议二、网络通信的java实现
1、IP地址:在Java中,使用java.NET包中的InetAddress类来描述IP地址。
2、InetAddress类的继承体系:
InetAddress
|--Inet4Address:用于表示IPV4
|--Inet6Address:用于表示IPV6
注意:InetAddress类没有构造方法,无法通过new去实例化对象。但是可以通过InetAddress类提供的静态方法来获取该类的对象,用该类接收。同时可以通过InetAddress类提供的相关方法来获取需要的信息,例如:IP地址、主机名等等。
InetAddress类的常用方法:
InetAddress getByName(String host):通过主机名获取InetAddress对象。
InetAddress getLocalHost():获取本机的InetAddress对象。
String getHostName():获取主机名。
String getHostAddress():获取主机的IP地址。
代码示例:/** * 网络通信的第一要素:IP地址,通过IP地址能唯一确定网络上的一台主机 * 网络通信中,使用InetAddress来代表IP地址,一个InetAddress对象就代表一个IP地址 */public class TestInternet { public static void main(String[] args) throws UnknownHostException { InetAddress inetAddress = InetAddress.getByName("www.baidu.com"); System.out.println(inetAddress); System.out.println(inetAddress.getHostName()); System.out.println(inetAddress.getHostAddress()); System.out.println("------------------------"); InetAddress inetAddress2 = InetAddress.getLocalHost(); System.out.println(inetAddress2); System.out.println(inetAddress2.getHostName()); System.out.println(inetAddress2.getHostAddress()); }}输出结果是:www.baidu.com/119.75.217.109www.baidu.com119.75.217.109------------------------ZYY-PC1609119/192.168.203.1ZYY-PC1609119192.168.203.13、端口:由于端口都是用数字进行标识,所以没有必要将端口封装成对象。4、Socket的基本介绍:
① Socket编程:通常所说的网络编程其实就是Socket编程。
②、什么是socket?
Socket的字面意思是插槽、插座的意思。其实,Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。
Socket通常也称作“套接字”,用于描述IP地址和端口。应用程序两端通过“套接字”向网络发出请求或者应答网络请求。
③、Socket和ServerSocket类位于java.Net包中。ServerSocket用于服务器端,Socket是建立网络连接时使用的。
在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。
不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类及其子类完成的。
④、Socket中的常用方法:
java.net.Socket类继承与Object,有8个构造方法。其中三个使用最频繁的方法:
void accept():用于获取连接到服务端的客户端对象,并且返回一个客户端的Socket对象实例。该方法是一个阻塞式方法。
"阻塞"使程序运行暂时"停留",直到一个会话产生,然后程序继续;通常"阻塞"是由循环产生的。
InputStream getInputStream():该方法获得网络连接输入,同时返回一个IutputStream对象实例,。OutputStream getOutputStream():该方法连接的另一端将得到输入,同时返回一个OutputStream对象实例。注意:其中getInputStream和getOutputStream方法均会产生一个IOException,它必须被捕获,因为它们返回的流对象,通常都会被另一个流对象使用。
5、传输协议TCP和UDP
①、UDP:User Datagram Protocol用户数据报协议
特点:
面向无连接:传输数据之前源端和目的端不需要建立连接。 每个数据报的大小都限制在64K(8个字节)以内。 面向报文的不可靠协议。(即:发送出去的数据不一定会接收得到) 传输速率快,效率高。 现实生活实例:邮局寄件、实时在线聊天、视频会议…等。
②、TCP:Transmission Control Protocol传输控制协议
特点:
面向连接:传输数据之前需要建立连接。 在连接过程中进行大量数据传输。 通过“三次握手”的方式完成连接,是安全可靠协议。 传输速度慢,效率低。 现实生活实例:打电话、下载文件…等。
代码实现:(1)TCP协议实现:
/** * 客户端给服务端发送信息,服务端吧信息输出到控制台上 * 在这个基础上增加服务端返回客户端信息,注意在客户端需要增加表示信息已经发送完毕的标识, * 因为服务端的read(inputStream的read方法是一个阻塞方法,而bufferedInputStream的read方法不是) * */public class TestTCP1 { @Test public void client(){ Socket socket = null; OutputStream os = null; InputStream cis = null; //创建socket,指明服务器端的IP和端口号 try { socket = new Socket(InetAddress.getByName("127.0.0.1"), 9090); os = socket.getOutputStream(); os.write("我是客户端".getBytes()); //以下是新增加的内容 socket.shutdownOutput(); cis = socket.getInputStream(); int len = 0; byte[] cbs = new byte[20]; while((len = cis.read(cbs)) != -1){ String string = new String(cbs, 0, len); System.out.println("这是客户端收到的信息:"+string); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(cis != null){ try { cis.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(os != null){ try { os.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(socket != null){ try { socket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } @Test public void server(){ ServerSocket serverSocket = null; Socket socket2 = null; InputStream is = null; OutputStream sos = null; try { serverSocket = new ServerSocket(9090); socket2 = serverSocket.accept(); is = socket2.getInputStream(); int len = 0; byte [] bs = new byte[20]; while((len = is.read(bs)) != -1){ String str = new String(bs, 0, len); System.out.println(str); } //以下是新增加的内容 sos = socket2.getOutputStream(); sos.write("我是服务端发送的信息".getBytes()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } finally{ if(sos != null){ try { sos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(is != null){ try { is.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(socket2 != null){ try { socket2.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(serverSocket != null){ try { serverSocket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }}(2)UDP协议实现public class TestUDP { @Test public void send() { DatagramSocket ds = null; try { ds = new DatagramSocket(); byte[] b = "我是要发送的数据".getBytes(); // 创建一个数据报,每一个数据报不能大于64K,都记录着数据信息,发送端的IP、端口号,以及要发送到的接口端IP及其端口号 DatagramPacket pack = new DatagramPacket(b, 0, b.length, InetAddress.getByName("127.0.0.1"), 9090); ds.send(pack); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if (ds != null) { ds.close(); } } } // @Test public void receive() { DatagramSocket ds = null; DatagramPacket pack = null; try { ds = new DatagramSocket(9090); byte[] b = new byte[1024]; pack = new DatagramPacket(b, 0, b.length); ds.receive(pack); String str = new String(pack.getData(), 0, pack.getLength()); System.out.println(str); } catch (SocketException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if (ds != null) { ds.close(); } } }}参考资料网址是:http://blog.csdn.net/liuhaomatou/article/details/41075701
http://blog.csdn.net/csh624366188/article/details/7331716
新闻热点
疑难解答