码迷,mamicode.com
首页 > 其他好文 > 详细

网络编程

时间:2019-05-11 23:08:23      阅读:137      评论:0      收藏:0      [点我收藏+]

标签:必须   hostname   计算   add   init   需求   local   ftp   ready   

 

1.1   网络概念

把多台计算机通过物理线路连接起来,就形成了网络。目的在于交换数据和共享信息。

 

1.1.1     网络通信的三要素

【1】IP地址:唯一标识网络上的每一台计算机。两台计算机之间通信的必备有素

【2】端口号:计算机中应用的标号(代表一个应用程序)

0-1024系统使用或保留端口

常见端口:http:80 stmp: 25 ftp:21

    有效端口0-65536,开发者可以的端口是1025-65536之间。一些第三方引用如mysql:3306 oracle:1251。

【3】通信协议:通信的规则 TCP,UDP

1.1.2     网络通信模型(B)

 技术图片

 

 

IP地址分类

 技术图片

 

 

特殊IP

•    0.0.0.0:本机

•    127.0.0.1:本机回环地址,用于本机测试

•    255.255.255.255:当前子网,一般用于向当前子网广播信息

 

1.2   InetAddress

InetAddress 表示IP地址。

 

 1 public class Test01 {
 2      public static void main(String[] args) {
 3          // 获取本机IP地址
 4          InetAddress ip1;
 5          try {
 6               ip1 = InetAddress.getLocalHost();
 7               // USER-20180113BT/192.168.2.56
 8               System.out.println(ip1.toString());
 9              
10               // 获取主机名称
11               System.out.println(ip1.getHostName());
12               System.out.println(ip1.getHostAddress());
13              
14          } catch (UnknownHostException e) {
15               e.printStackTrace();
16          }
17      }
18 }

 

1.3   TCP 编程

TCP编程中,如果要完成通信,通信双方必须要创建socket,通过socket完成通信。

 

TCP通信步骤

[1] 服务器启动ServerSocket作为通信的Server端,等待客户端链入。

[2] 客户端创建Socket作为通信的Client端

[3] Client端链入Server端后建立可靠的双向的持续性的点对点的通讯连接,即可通信。

 

案例:完成一次单向通信。

服务器端

 1 package cn.sxt01.net01;
 2  
 3 import java.io.IOException;
 4 import java.io.OutputStream;
 5 import java.net.ServerSocket;
 6 import java.net.Socket;
 7  
 8 public class Server01 {
 9      public static void main(String[] args) {
10         
11          System.out.println("服务器启动...");
12         
13          // 【1】创建server socket
14          ServerSocket serverSocket = null;
15          Socket clientSocket = null;
16          try {
17         
18               serverSocket = new ServerSocket(8000);
19               // 【2】等待客户端的链入->阻塞式函数->监听8000端口,看是否有client链入
20               clientSocket = serverSocket.accept();
21              
22               System.out.println(clientSocket.getInetAddress().getHostAddress()+"链入!");
23         
24               // 【3】给客户端主动发信息
25               OutputStream out = clientSocket.getOutputStream();
26              
27               String msg = "hello 兄弟";
28               byte[] buf = msg.getBytes("UTF-8");
29               out.write(buf);
30               clientSocket.shutdownOutput();
31              
32               out.close();
33              
34         
35          } catch (IOException e) {
36               e.printStackTrace();
37          }
38      }
39 }
40  

 

 

客户端

 1 package cn.sxt02.net01;
 2  
 3 import java.io.IOException;
 4 import java.io.InputStream;
 5 import java.net.Socket;
 6  
 7 public class Client01 {
 8     public static void main(String[] args) {
 9         System.out.println("客户端运行...");
10        
11         // 【1】创建客户端socket
12         Socket socket = null;
13         try {
14             socket = new Socket("192.168.2.56", 8000);
15            
16             // 【2】接收来自服务器的消息
17             InputStream in = socket.getInputStream();
18             byte[] buf = new byte[1024];
19             int len = in.read(buf);
20            
21             String msg = new String(buf, 0, len, "UTF-8");
22             System.out.println(msg);
23            
24         } catch (IOException e) {
25             e.printStackTrace();
26         }
27     }
28 }

 

常见问题

[1] 端口被占用

java.net.BindException: Address already in use: JVM_Bind

     at java.net.DualStackPlainSocketImpl.bind0(Native Method)

     at java.net.DualStackPlainSocketImpl.socketBind(DualStackPlainSocketImpl.java:106)

     at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:387)

     at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:190)

     at java.net.ServerSocket.bind(ServerSocket.java:375)

     at java.net.ServerSocket.<init>(ServerSocket.java:237)

     at java.net.ServerSocket.<init>(ServerSocket.java:128)

     at cn.sxt01.net02.Server01.main(Server01.java:19)

 

[2] 服务器未启动

java.net.ConnectException: Connection refused: connect

     at java.net.DualStackPlainSocketImpl.connect0(Native Method)

     at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)

     at cn.sxt02.net02.Client01.main(Client01.java:15)

 

[3] 连接超时异常 SocketTimeoutException

当网速很慢时,可能发生连接超时异常。

1.4   UDP 编程

UDP编程中,如果要完成通信,通信双方必须要创建DatagramSocket,通过DatagramSocket完成通信。

 

数据报包用来实现无连接包投递服务。每条报文仅根据该包中包含的信息从一台机器路由到另一台机器

 

UDP步骤:

[1] 创建一个DatagramSocket用于表示发送端,通过send方法发送数据报

[2] 创建一个DatagramSocket用于表示接收端,通过receive方法发送数据报

 

需求:完成一次单向的UDP通信。

发送端

public static void main(String[] args) {
         
         // 发送端:主动发送信息
         System.out.println("发送端开始发送信息...");
         // 【1】创建socket并指定发送数据的端口
         DatagramSocket socket = null;
         try {
              socket = new DatagramSocket(8000);
              
              // 【2】创建数据报包
              String msg = "hello B";
              byte[] buf = msg.getBytes("UTF-8");
              DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getLocalHost(), 9000);
              
              // 【3】发送
              socket.send(dp);
              
              // 【4】关闭
              socket.close();
         } catch (SocketException e) {
              e.printStackTrace();
         } catch (UnsupportedEncodingException e) {
              e.printStackTrace();
         } catch (UnknownHostException e) {
              e.printStackTrace();
         } catch (IOException e) {
              e.printStackTrace();
         }
     }

 

接收端

 1 public static void main(String[] args) {
 2          // 接收端:接收信息
 3          System.out.println("启动接收端...");
 4          // 【1】创建一个 DatagramSocket
 5          DatagramSocket socket = null;
 6          try {
 7               socket = new DatagramSocket(9000);
 8               // 【2】接收消息
 9               byte[] buf = new byte[1024];
10               DatagramPacket dp = new DatagramPacket(buf, buf.length);
11               System.out.println("等待接收信息...");
12               socket.receive(dp);
13               System.out.println("接收完成...");
14               
15               // 处理接收的信息
16               String msg = new String(buf, 0, dp.getLength(), "UTF-8");
17               System.out.println(msg);
18               
19          } catch (SocketException e) {
20               e.printStackTrace();
21          } catch (IOException e) {
22               e.printStackTrace();
23          }
24      }

 

 

 

需求:实现双向通信

发送端

 1 public static void main(String[] args) {
 2          
 3          // 发送端:主动发送信息
 4          System.out.println("发送端开始发送信息...");
 5          Scanner sc = new Scanner(System.in);
 6          // 【1】创建socket并指定发送数据的端口
 7          DatagramSocket socket = null;
 8          try {
 9               socket = new DatagramSocket(8000);
10               
11               for(;;) {
12                    System.out.print("A说:");
13                    String msg = sc.nextLine();
14                    byte[] buf = msg.getBytes("UTF-8");
15                    DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getLocalHost(), 9000);
16                    
17                    // 【3】发送
18                    socket.send(dp);
19                    
20                    
21                    // 接收消息
22                    byte[] revBuf = new byte[1024];
23                    DatagramPacket revDp = new DatagramPacket(revBuf,revBuf.length);
24                    socket.receive(revDp);
25                    String revStr = new String(revBuf, 0, revDp.getLength(), "UTF-8");
26                    System.out.println(dp.getAddress().getHostName()+":"+revStr);
27               }
28               
29          } catch (SocketException e) {
30               e.printStackTrace();
31          } catch (UnsupportedEncodingException e) {
32               e.printStackTrace();
33          } catch (UnknownHostException e) {
34               e.printStackTrace();
35          } catch (IOException e) {
36               e.printStackTrace();
37          }finally {
38               // 【4】关闭
39               socket.close();
40          }
41      }

 

 

 

接收端

 1     public static void main(String[] args) {
 2          // 接收端:接收信息
 3          System.out.println("启动接收端...");
 4          Scanner sc = new Scanner(System.in);
 5          // 【1】创建一个 DatagramSocket
 6          DatagramSocket socket = null;
 7          
 8          try {
 9               socket = new DatagramSocket(9000);
10               
11               for(;;) {
12                    // 接收信息
13                    byte[] buf = new byte[1024];
14                    DatagramPacket dp = new DatagramPacket(buf, buf.length);
15                    socket.receive(dp);
16                    String msg = new String(buf, 0, dp.getLength(), "UTF-8");
17                    System.out.println(dp.getAddress().getHostName()+":"+msg);
18                    
19                    // 发送信息
20                    System.out.println("B说:");
21                    String sendMsg = sc.nextLine();
22                    byte[] sendBuf = sendMsg.getBytes("UTF-8");
23                    DatagramPacket sendDp = new DatagramPacket(sendBuf, 0, sendBuf.length, dp.getAddress(), dp.getPort());
24                    socket.send(sendDp);
25               }
26               
27          } catch (SocketException e) {
28               e.printStackTrace();
29          } catch (IOException e) {
30               e.printStackTrace();
31          }finally {
32               socket.close();
33          }
34      }

 

网络编程

标签:必须   hostname   计算   add   init   需求   local   ftp   ready   

原文地址:https://www.cnblogs.com/l3344/p/10850444.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!