黑马程序员11_网络
网络
1、概述:
网络编程的本质是两个设备之间的数据交换,当然,在计算机网络中,设备主要指计算机。数据传递本身没有多大的难度,不就是把一个设备中的数据发送给两外一个设备,然后接受另外一个设备反馈的数据。现在的网络编程基本上都是基于请求/响应方式的,也就是一个设备发送请求数据给另外一个,然后接收另一个设备的反馈。在网络编程中,发起连接程序,也就是发送第一次请求的程序,被称作客户端(Client),等待其他程序连接的程序被称作服务器(Server)。客户端程序可以在需要的时候启动,而服务器为了能够时刻相应连接,则需要一直启动。
例如以打电话为例,首先拨号的人类似于客户端,接听电话的人必须保持电话畅通类似于服务器。连接一旦建立以后,就客户端和服务器端就可以进行数据传递了,而且两者的身份是等价的。
网络模型
OSI参考模型
TCP/IP参考模型
2、网络通讯要素
①IP地址:
网络中设备的标识
不易记忆,可用主机名
本地回环地址:127.0.0.1 主机名:localhost
②端口号:
用于标识进程的逻辑地址,不同进程的标识
有效端口:0~65535,其中0~1024系统使用或保留端口。
备注:不是所谓的物理端口!
③传输协议:
通讯的规则
常见协议:TCP,UDP
IP
知识点一:
getHostName和getHostAddress获得本机名以及本机地址
代码如下:
public static void main(String[] args) throws Exception { InetAddress i = InetAddress.getLocalHost(); print(i.getHostAddress());//127.0.0.1 print(i.getHostName()); //san print(i); //san/127.0.0.1 }
知识点二:
InetAddress.getByName()获得任意主机地址,传入名字得到地址
代码如下:
InetAddress ia = InetAddress.getByName("thinkpad-sl400"); InetAddress ia = InetAddress.getByName("192.168.1.0"); InetAddress ia = InetAddress.getByName("www.baidu.com");
Socket
Socket就是为网络服务提供的一种机制。通信的两端都有Socket。网络通信其实就是Socket间的通信。数据在两个Socket间通过IO传输。
UDP
特点:
1、将数据源和目的地封装到数据包中,不需要建立连接
2、每个数据包的大小限制在64k以内
3、因无连接,是不可靠协议
4、不需要建立连接,速度快
知识点一:建立UDP的Socket服务发送
需求:通过udp传输方式,将一段文字数据发送出去。,
定义一个udp发送端。
思路:
1、建立updsocket服务。
2、提供数据,并将数据封装到数据包中。
3、通过socket服务的发送功能,将数据包发出去。
4、关闭资源。
代码如下:
//1,创建udp服务。通过DatagramSocket对象。 DatagramSocket ds = new DatagramSocket(8888); //2,确定数据,并封装成数据包。 DatagramPacket(byte[] buf, int length,InetAddress address, int port) byte[] buf = "hahah ,chen lu lai le".getBytes(); DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("127.0.0.1"),1000); //3,通过socket服务,将已有的数据包发送出去。通过send方法。 ds.send(dp); //4,关闭资源。 ds.close(); 此时没有接收端,数据丢失。
知识点二:建立UDP的Socket服务接收
1、定义udpsocket服务。通常会监听一个端口。其实就是给这个接收网络应用程序定义数字标识。方便于明确哪些数据过来该应用程序可以处理。
2、定义一个数据包,因为要存储接收到的字节数据。因为数据包对象中有更多功能可以提取字节数据中的不同数据信息。
3、通过socket服务的receive方法将收到的数据存入已定义好的数据包中。
4、通过数据包对象的特有功能。将这些不同的数据取出。打印在控制台上。
5、关闭资源。
代码如下:
public static void main(String[] args) throws Exception { DatagramSocket ds = new DatagramSocket(6789);//与发送端的接口对应 byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf,buf.length); String data = new String(dp.getData(),0,dp.getLength()); ds.receive(dp); print(dp.getAddress().getHostName()); print(dp.getAddress().getHostAddress()); print(dp.getLength()); print(dp.getPort()); print(dp.getSocketAddress()); print(data); ds.close(); }
练习:UDP聊天程序
import java.io.*; import java.net.*; class Send implements Runnable { private DatagramSocket ds; Send(DatagramSocket ds) { this.ds = ds; } public void run() { try { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); //接收键盘的输入 String line = null; while((line = br.readLine())!=null) //读取键盘的输入 { if(line.equals("886")) break; byte[] buf = line.getBytes(); //将键盘的输入转为字节数组 //将键盘输入的字节数组装入数据包中,发送给指定的ip,指定的端口 DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.255"),10011); ds.send(dp); //发送数据包 } }catch(Exception e){} } } class Rece implements Runnable { private DatagramSocket ds; Rece(DatagramSocket ds) //初始时就有Socket服务 { this.ds = ds; } public void run() { try { while(true) { byte[] buf = new byte[1024]; //创建字节数组 DatagramPacket dp = new DatagramPacket(buf,buf.length); //将字节数组装入数据包,用以接收数据 ds.receive(dp); //接收数据包 String ip = dp.getAddress().getHostAddress(); //获取数据包中的ip String data = new String(dp.getData(),0,dp.getLength()); //获取数据包中的数据 System.out.println(ip+"::"+data); } } catch(Exception e){} } } public class chat { public static void main(String[] args) throws Exception { Send sd = new Send(new DatagramSocket()); Rece re = new Rece(new DatagramSocket(10011)); new Thread(sd).start(); new Thread(re).start(); } }
TCP
特点: 1、建立连接,形成传输数据的通道
2、在连接中进行大量数据的传输
3、通过三次握手完成连接、是可靠协议
4、必须建立连接,效率会稍低
知识点一:tcp分客户端Socket和服务端ServerSocket。
- 客户端Socket:
客户端对应的对象是Socket。通过查阅socket对象,发现在该对象建立时,就可以去连接指定主机。因为tcp是面向连接的。所以在建立socket服务时,就要有服务端存在,并连接成功。形成通路后,在该通道进行数据的传输。
- 客户端Socket建立的步骤:
1、创建Socket服务。并指定要连接的主机和端口。
2、获得OutputStream
3、将发送数据转换为字节数组发送出
4、关闭Socket
代码如下:
-
//1、创建Socket服务。并指定要连接的主机和端口。 Socket s = new Socket("127.0.0.1",10020); //2、获得OutputStream OutputStream os = s.getOutputStream(); //3、将发送数据转换为字节数组发送出 os.write(("chen lu lai le ").getBytes()); //4、关闭资源 s.close();
1、建立服务端的socket服务。ServerSocket();并监听一个端口。
2、获取连接过来的客户端对象。通过ServerSokcet的 accept方法。没有连接就会等,所以这个方法阻塞式的。
3、客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取到该客户端对象的读取流来读取发过来的数据。并打印在控制台。
4、关闭服务端。(可选)
//1、建立服务端的Socket服务,监听一个端口 ServerSocket ss = new ServerSocket(10020); //2、获取链接过来的的客户端 Socket sss = ss.accept(); //3、获取该客户端对象的读取流 InputStream is = sss.getInputStream(); //建立字节数组,以便装入接收的数据 byte[] buf = new byte[1024]; //把读取的数据装入字节数组 int len = is.read(buf); //将字节数组转换为字符串 String str = new String(buf,0,len); System.out.println(sss.getInetAddress().getHostAddress()+str); sss.close();
陈潞的补充:发送消息用OutputStream(对象).write();接收消息用InputStream(对象).read()