关于TCP/IP协议及网络通信相关问题

一、网络模型:

OSI标准模型七层架构以及其传输数据的模型如下:

 

传输信息的过程由上之下逐渐封装,接收过程则是由下至上逐渐拆包,每一层只解析自己独立的部分。

二、网络的机要素

1、IP

1 public class NetTest {
2     public static void main(String[] args) throws UnknownHostException {
3         //获取本地ip
4         InetAddress ip = InetAddress.getLocalHost();
5         System.out.println(ip);
6     }
7 }

 

2、域名

  本地ip和域名映射文件  :  C:\Windows\System32\drivers\etc\hosts

 

  当用户访问的是服务器对应的域名时候,首先会在本地该映射文件中找,如果没有,则访问第三方厂商提供的域名解析器进行解析,最终将域名解析为ip地址进行访问。如下图:

 

 

3、端口port

  为了能够实现应用程序之间的通讯,引入端口来区分。例如飞秋和qq之间的通讯。

4、传输层协议

  传输层协议有一下几个TCP 、UDP 、 TLS 、 DCCP 、 SCTP 、RSVP 、 PPTP,常用的有TCP和UDP。

 

 UDP:

  面向无连接;将数据及源和和目的封装成包,不需要建立连接;每一个数据包的大小限制在64kb以内;不需要连接,因此速度快;不安全(例如qq发送消息)。

TCP:

  需要建立连接,形成传输通道;在连接中进行大量的数据传输;通过三次握手完成连接,是安全可靠的;同比效率较低(例如用qq传递文件)。

5、网络传输中的重要概念Soket

  它是为通讯提供的一种机制;通信的两端都有Soket;网络通讯的实质就是Soket之间的通讯;数据在两个Soket之间及进行IO传输。

 

 6、UDP

  UDP传输如同码头、船、集装箱和货物一样;发送的信息如同货物,DatagramPacket就是集装箱,多大的货物就要用对应的集装箱;传输协议如同船只,soket就是码头。接收端必须要有明确的端口。然后用自己的DatagramPacket(集装箱去封装货物)。代码和步骤如下:

 1 //基于UDP传输协议的多人聊天示例
 2 public class UdpChat {
 3     public static void main(String[] args) throws Exception {
 4         DatagramSocket dsk = new DatagramSocket();
 5         DatagramSocket res = new DatagramSocket(10001);//接收方必须有固定端口
 6         Send_Port send = new Send_Port(dsk);
 7         Resive_Port resv = new Resive_Port(res);
 8         new Thread(send).start();;
 9         new Thread(resv).start();;
10     }
11 }
12 
13 /*
14  * 发送端
15  */
16 class Send_Port implements Runnable{
17     /*
18      * 步骤:
19      *     1、创建UDP的Soket,使其具备发送能力;
20      *     2、创建及封装需要传输的数据;
21      *     3、使用Soket的send方法进行发送;
22      *     4、关闭资源。
23      */    
24     
25     //该对象用于发送
26     private DatagramSocket dsk;
27     public Send_Port(DatagramSocket sp) {
28         super();
29         this.dsk = sp;
30     }
31     @Override
32     public void run() {
33         //键盘输入文本
34         BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
35         String line = null;
36         System.out.println("请输入:");
37         try {
38             while((line = bf.readLine()) != null) {
39                 if("886".equals(line)) {
40                     System.out.println("发送方终止通话");
41                     break;
42                 }
43                 byte[] bt = line.getBytes();
44                 /*参数:需要传输的数据;数据长度,接收方的ip地址,接收方的端口号*/
45                 DatagramPacket packg = new DatagramPacket(bt, bt.length, InetAddress.getByName("172.16.10.255"), 10001);
46                 dsk.send(packg);
47             }
48             dsk.close();//关闭资源
49         } catch (IOException e) {
50             e.printStackTrace();
51         }
52     }
53 }
54 
55 /*
56  * 接收端
57  */
58 class Resive_Port implements Runnable{
59     /*
60      * 步骤:
61      *     1、创建UDP的Soket,用于接收
62      *     2、创建接受包,用于接收传递来的数据,其中需要规定接收专用的集合及其大小
63      *     3、接收数据
64      *     4、关闭资源。
65      */    
66     private DatagramSocket drk;
67     //初始化参数
68     public Resive_Port(DatagramSocket drk) {
69         super();
70         this.drk = drk;
71     }
72     @Override
73     public void run() {
74         byte[] res_byte = new byte[1024];
75         DatagramPacket res = new DatagramPacket(res_byte , res_byte.length);//相当于集装箱。
76         while(true) {
77             try {
78                 drk.receive(res);
79                 String text = new String(res.getData(),0,res.getData().length);
80                 if(text!=null) {
81                     DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
82                     String date = df.format(new Date());
83                     if("886".equals(text)) {
84                         System.out.println("用户:"+res.getAddress()+"退出群聊!");
85                     }
86                     System.out.println(res.getAddress()+":"+text);
87                     System.out.print(date);
88                 }
89             } catch (IOException e) {
90                 e.printStackTrace();
91             }
92         }
93     }
94 }

 

7、TCP

  面向连接,详情人如下:

 1 public class TCPTest {
 2     /**
 3      * 服务端编程思想:(开启后将处于阻塞状态)
 4      *     1、创建服务端Socket,监听一个明确的端口;
 5      *     2、获取客户端对象(不用自己创建流)
 6      *     3、根据客户端对象获取到对应的输入流,读取客户端发来数据
 7      *     4、逻辑处理
 8      *     5、
 9      * @throws Exception 
10      */
11     public static void main(String[] args) throws Exception {
12         
13         //服务端socket,监听一个端口
14         ServerSocket ss = new ServerSocket(10003);
15         Service ser = new Service(ss);
16         ser.server();
17     }
18 }
19 
20 class test{
21     /**
22      * 客户端编程思路:
23      *     1、创建客户端Soket,明确服务端的地址和端口。
24      *     2、三次握手,建立通道,如果通道建立成功,客户端和服务器就会形成Soke IO流。
25      *         客户端的任务就是获取到Socket中的输出流将,将信息传输服务器中。
26      *     3、通过输出流发送数据
27      *     4、关闭资源
28      * 
29      * 注意事项:面向连接编程首先应该先启动服务器,这样客户端才能够像服务器发送请求
30      */
31     public static void main(String[] args) throws Exception {
32         //客户端socket,明确服务端ip和port
33         Socket s = new Socket(InetAddress.getByName("172.16.10.23"),10003);
34         Client cl = new Client(s);
35         cl.client();
36     }
37 }
38 
39 class Client{
40     /*客户端socket*/
41     private Socket client_socket;
42     /* 初始化参数 */
43     public Client(Socket client_socket) {
44         super();
45         this.client_socket = client_socket;
46     }
47     public void client() throws Exception {
48         OutputStream out = null;
49         try {
50             System.out.println("客户端开始请求资源");
51             out = client_socket.getOutputStream();
52             out.write("请求资源".getBytes());
53         } catch (IOException e) {
54             throw new Exception("连接超时:"+ e);
55         }finally{
56             out.close();
57         }
58     }
59 }
60     
61 class Service{
62     private ServerSocket service ;
63     public Service(ServerSocket service) {
64         super();
65         this.service = service;
66     }
67     /*阻塞状态*/
68     public void server() throws Exception {
69         System.out.println("服务器初始化完成...");
70         //获取客户端
71         Socket client = service.accept();
72         if(client!=null) {
73             //从客户端中获取输入流
74             InputStream in = client.getInputStream();
75             //读取
76             byte[] bt = new byte[1024];
77             int line = in.read(bt);
78             String text = new String(bt,0,line);
79             String ip = client.getInetAddress().getHostAddress();
80             System.out.println(ip+":"+text);
81             client.close();
82         }
83     }
84 }

 

  

 

posted on 2017-10-25 18:04  未知名的艺术家  阅读(137)  评论(0编辑  收藏  举报

导航