本文共 5937 字,大约阅读时间需要 19 分钟。
笔记自用 ,来源阳光沙滩:拉大锯
网络模型分为:OSI参考模型和TCP/IP参考模型,如下图
用户在应用层里遨游,我们搞开发在传输层和网际层里遨游。简答一点来讲,数据先是从应用层往下走封装打包后,在经过网络层传输到接受端,接收端自下而上拆包,得到用户发送的数据。
IP地址,端口,和传输协议
IP地址,就跟酒店房间号码差不多一个意思。一些特殊的IP地址,本地的:127.0.0.1,主机名:localHost 也可以去DOC命令行 输入ipconfig查看网络配置 在Java中有一个Inet Address类,可以获得IP地址 Inet Address类没有构造方法,无法实例化,采用的是单例设计模式,可以通过它本身的方法拿到对象
import java.net.*;public class Demo{ public static void main(String[] args)throws Exception{ //获取InetAddress对象 InetAddress ia = InetAddress.getLocalHost(); //获取IP地址 String ip = ia.getHostAddress(); //一步到位 //InetAddress ia = InetAddress.getLocalHost().getHostAddress(); System.out.println("本机IP地址为:"+ip); }}
上面的端口指的是是逻辑端口:
1、端口的范围从0~65535(2的16次方减1) 2、系统保留端口为:0~1024 3、一些常用的端口,FTP:21,SMTP:25,HTTP:80
TCP协议 |
---|
说明:是面向连接的协议,要建立连接后在进行传输数据,常用于上传下载 |
是否面向连接:是建立连接,三次握手的机制,友好 |
数据包大小:建立连接后进行大数据传输 |
是否可靠:是,毕竟三次握手 |
特别:一定要先建立连接,速度相比UDP不快 |
关于三次握手:
Client说:服务端哥,我想联你,在吗?—————>请求链接 Server说:客户端弟,我在的,你联过来吧!———->服务端确认链接 Client说:那好,我真的联上来啦!——————–>客户端确认链接 计算机与计算机之间的通信步骤: 1、通过IP地址找到主机;2、通过端口找到接收的程序;3、通过协议发送数据。
UDP,不面向连接,不可靠,速度快,一般用于聊天等一次性的数据传输,不要精确数据或者永久数据下使用。
在说这两个传输协议之前,要提到的是Socket,Socket大概是插座的意思,那么这里呢可以理解为网线插口,比喻成港口。 如何让两台主机之间传输数据,我们需要一个Socket,也就是一个港口。 UDP的港口是DatagramSocket,它可以接受和发送数据“包”。一般发送的话要指定IP地址,还有端口,而接受端可以不指定IP,但要监视端口。
发送端:
接受端: 下面模拟一个聊天器: 客户端: //接收端import java.net.*;public class Server{ public static void main(String[] args){ //1:创建服务 DatagramSocket ds = null; DatagramPacket dp = null; try{ if(ds==null) ds = new DatagramSocket(10004); //2:创建缓冲区 byte[] buf = new byte[1024]; //3:接收数据 if(dp==null) dp = new DatagramPacket(buf,buf.length); ds.receive(dp); //知道是谁发来的数据 String ip = dp.getAddress().getHostName(); //4:输出数据到控制台上 System.out.println(ip+" :"+new String(buf, 0, dp.getLength())); //5:关闭资源 }catch(Exception e){ System.out.println("出问题了!"); }finally{ ds.close(); } }}
服务端:
//接收端import java.net.*;public class Server{ public static void main(String[] args){ //1:创建服务 DatagramSocket ds = null; DatagramPacket dp = null; try{ if(ds==null) ds = new DatagramSocket(10004); //2:创建缓冲区 byte[] buf = new byte[1024]; //3:接收数据 if(dp==null) dp = new DatagramPacket(buf,buf.length); ds.receive(dp); String ip = dp.getAddress().getHostName(); //4:输出数据到控制台上 System.out.println(ip+" :"+new String(buf,0,dp.getLength())); //5:关闭资源 }catch(Exception e){ System.out.println("出问题了!"); }finally{ ds.close(); } }}
利用线程多次发送消息:
import java.io.*;import java.net.*;public class ChatDemo { public static void main(String[] args) { //创建读取线程 new Thread(new ChatThread()).start(); // 创建服务 DatagramSocket ds = null; BufferedReader br = null; try { if (ds == null) ds = new DatagramSocket(); // 读取键盘录入 if (br == null) br = new BufferedReader(new InputStreamReader(System.in)); // 读取数据 String line = null; while ((line = br.readLine()) != null) { // 发送数据 byte[] buf = line.getBytes(); DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("PresidentsPC"), 9998); ds.send(dp); } } catch (Exception e) { System.out.println(e.toString()); } finally { ds.close(); if (br != null) try { br.close(); } catch (Exception e) { System.out.println(e.toString()); } } }}//搞一个线程来接受数据class ChatThread implements Runnable { public void run(){ while(true){ DatagramSocket ds = null; try { ds = new DatagramSocket(9998);//监视9998端口 //获取数据 byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf,buf.length); ds.receive(dp); //获取IP String ip = dp.getAddress().getHostAddress(); //输出数据 System.out.println(ip+" :"+new String(buf,0,dp.getLength())); } catch (Exception e) { System.out.println(e.toString()); }finally{ ds.close(); } } }}
TCP的套路和UDP的差不多,就是客户端的服务是Sokcet,服务端的服务是ServerSocket。
客户端:
import java.io.*;import java.net.*;public class Client { public static void main(String[] args) { // 1:创建服务 Socket st = null; try { if (st == null) st = new Socket("PresidentsPC", 13000); //2:把数据转换成字节数组 byte[] buf = "超前夕第".getBytes(); //获取输出流 发送给服务端 OutputStream out = st.getOutputStream(); //发送数据 out.write(buf); //关闭发送流 st.shutdownOutput(); //3:获取输入流,获取反馈信息 InputStream in = st.getInputStream(); byte[] buffer = new byte[1024]; int len = in.read(buffer); //4:打印反馈信息,关闭资源 System.out.println(new String(buffer,0,len)); } catch (Exception e) { System.out.println(e.toString()); }finally{ if(st!=null){ try{ st.close(); }catch(Exception e) { System.out.println(e.toString());} } } }}
服务端:
import java.io.*;import java.net.*;public class Server { public static void main(String[] args)throws Exception { //1.创建服务 利用ServerSocket的accept方法 ServerSocket ss = new ServerSocket(13000); Socket s = ss.accept(); //搞到IP地址 String ip = s.getInetAddress().getHostAddress(); //输出链接上来的机器 System.out.println(ip+"-----connected"); //2:获取输入流 InputStream in = s.getInputStream(); //3:读取数据 byte[] buf = new byte[1024]; int len = 0; while((len = in.read(buf))!=-1){ //打印到控制台上吧 System.out.println(new String(buf,0,len)); } s.shutdownInput(); //发送反馈信息 OutputStream out = s.getOutputStream(); out.write("服务端收到啦".getBytes()); //5:关闭资源 s.close(); ss.close(); }}
转载地址:http://whrii.baihongyu.com/