博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
网络编程
阅读量:4311 次
发布时间:2019-06-06

本文共 14277 字,大约阅读时间需要 47 分钟。

1. 网络概念

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

 1)网络通信的三要素

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

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

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

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

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

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

2) 网络通信模型

 

 

 

IP地址分类

 

 

 

特殊IP

0.0.0.0:本机

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

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

 

2.  InetAddress

InetAddress 表示IP地址。

1 publicclass Test01 { 2  3      publicstaticvoid main(String[] args) { 4  5          // 获取本机IP地址 6  7          InetAddress ip1; 8  9          try {10 11               ip1 = InetAddress.getLocalHost();12 13               // USER-20180113BT/192.168.2.5614 15               System.out.println(ip1.toString());16 17              18 19               // 获取主机名称20 21               System.out.println(ip1.getHostName());22 23               System.out.println(ip1.getHostAddress());24 25              26 27          } catch (UnknownHostException e) {28 29               e.printStackTrace();30 31          }32 33      }34 35 }

3.  TCP编程

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

 

TCP通信步骤

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

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

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

 

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

服务器端

1 package cn.sxt01.net01; 2  3   4  5 import java.io.IOException; 6  7 import java.io.OutputStream; 8  9 import java.net.ServerSocket;10 11 import java.net.Socket;12 13  14 15 publicclass Server01 {16 17      publicstaticvoid main(String[] args) {18 19         20 21          System.out.println("服务器启动...");22 23         24 25          // 【1】创建server socket26 27          ServerSocket serverSocket = null;28 29          Socket clientSocket = null;30 31          try {32 33         34 35               serverSocket = new ServerSocket(8000);36 37               // 【2】等待客户端的链入->阻塞式函数->监听8000端口,看是否有client链入38 39               clientSocket = serverSocket.accept();40 41              42 43               System.out.println(clientSocket.getInetAddress().getHostAddress()+"链入!");44 45         46 47               // 【3】给客户端主动发信息48 49               OutputStream out = clientSocket.getOutputStream();50 51              52 53               String msg = "hello 兄弟";54 55               byte[] buf = msg.getBytes("UTF-8");56 57               out.write(buf);58 59               clientSocket.shutdownOutput();60 61              62 63               out.close();64 65              66 67         68 69          } catch (IOException e) {70 71               e.printStackTrace();72 73          }74 75      }76 77 }

客户端

 

1 package cn.sxt02.net01; 2  3   4  5 import java.io.IOException; 6  7 import java.io.InputStream; 8  9 import java.net.Socket;10 11  12 13 publicclass Client01 {14 15     publicstaticvoid main(String[] args) {16 17         System.out.println("客户端运行...");18 19        20 21         // 【1】创建客户端socket22 23         Socket socket = null;24 25         try {26 27             socket = new Socket("192.168.2.56", 8000);28 29            30 31             // 【2】接收来自服务器的消息32 33             InputStream in = socket.getInputStream();34 35             byte[] buf = newbyte[1024];36 37             intlen = in.read(buf);38 39            40 41             String msg = new String(buf, 0, len, "UTF-8");42 43             System.out.println(msg);44 45            46 47         } catch (IOException e) {48 49             e.printStackTrace();50 51         }52 53     }54 55 }

常见问题

[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 public class Test01 { 2     public static void main(String[]args) throws IOException, ClassNotFoundException{ 3          4         System.out.println("服务器启动中..."); 5         ServerSocket serverSocket=new ServerSocket(11000); 6         while(true){ 7             Socket clinetSocket=serverSocket.accept(); 8             MyThread myThread=new MyThread(clinetSocket); 9             myThread.start();10         }11     }12 }
1 public class MyThread extends Thread { 2  3     private Socket socket; 4  5     public MyThread() { 6         super(); 7     } 8  9     public MyThread(Socket socket) {10         super();11         this.socket = socket;12     }13     @Override14     public void run() {15         InputStream in=null;16         ObjectInputStream ois=null;17         OutputStream out=null;18         DataOutputStream dos=null;19         20         try {21             //接收来自客户端的信息22             in=socket.getInputStream();23             ois=new ObjectInputStream(in);24             User user= (User) ois.readObject();25             socket.shutdownInput();26             27             String str;28             if(user.getName().equals("111") && user.getPwd().equals("123")){29                 str="成功登陆";30             }else{31                 str="用户名或密码错误,登陆失败";32             }33             //返回给客户端的信息34             out=socket.getOutputStream();35             dos=new DataOutputStream(out);36             dos.writeUTF(str);37             socket.shutdownOutput();38             39             in.close();40             ois.close();41             dos.close();42             out.close();43             socket.close();44         } catch (ClassNotFoundException e) {45             e.printStackTrace();46         } catch (IOException e) {47             e.printStackTrace();48         }49     }50 }
1 public class User implements Serializable { 2  3     private static final long serialVersionUID = 4478328638580552366L; 4     private String name; 5     private String pwd; 6  7     public String getName() { 8         return name; 9     }10 11     public void setName(String name) {12         this.name = name;13     }14 15     public String getPwd() {16         return pwd;17     }18 19     public void setPwd(String pwd) {20         this.pwd = pwd;21     }22 23     public User() {24         super();25     }26 27     public User(String name, String pwd) {28         super();29         this.name = name;30         this.pwd = pwd;31     }32 33     @Override34     public String toString() {35         return "User [name=" + name + ", pwd=" + pwd + "]";36     }37 38 }

客户端

1 public class Test01 { 2     public static void main(String [] args){ 3          4         Scanner sc=new Scanner(System.in); 5         System.out.println("请输入登录名:"); 6         String name=sc.nextLine(); 7          8         System.out.println("请输入密码:"); 9         String pwd=sc.nextLine();10         11         User user=new User(name,pwd);12         13         try {14             // 传输请求给服务器15             Socket socket=new Socket("127.0.0.1",11000);16             OutputStream out=socket.getOutputStream();17             ObjectOutputStream oos=new ObjectOutputStream(out);18             19             oos.writeObject(user);20             socket.shutdownOutput();21             22             //接收来自服务器的信息23             InputStream in=socket.getInputStream();24             DataInputStream dis=new DataInputStream(in);25             26             String str=dis.readUTF();27             System.out.println(str);28             29             30         } catch (UnknownHostException e) {31             e.printStackTrace();32         } catch (IOException e) {33             e.printStackTrace();34         }35         36         37     }38 }
1 public class User implements Serializable { 2  3     private static final long serialVersionUID = 4478328638580552366L; 4     private String name; 5     private String pwd; 6  7     public String getName() { 8         return name; 9     }10 11     public void setName(String name) {12         this.name = name;13     }14 15     public String getPwd() {16         return pwd;17     }18 19     public void setPwd(String pwd) {20         this.pwd = pwd;21     }22 23     public User() {24         super();25     }26 27     public User(String name, String pwd) {28         super();29         this.name = name;30         this.pwd = pwd;31     }32 33     @Override34     public String toString() {35         return "User [name=" + name + ", pwd=" + pwd + "]";36     }37 38 }

4.  UDP编程

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

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

 

UDP步骤:

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

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

 先运行接收端,再运行发送端!!!

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

发送端

1 public static void main(String[] args) { 2  3          4  5          // 发送端:主动发送信息 6  7          System.out.println("发送端开始发送信息..."); 8  9          // 【1】创建socket并指定发送数据的端口10 11          DatagramSocketsocket = null;12 13          try {14 15               socket = newDatagramSocket(8000);16 17              18 19               // 【2】创建数据报包20 21               String msg = "hello B";22 23               byte[] buf = msg.getBytes("UTF-8");24 25               DatagramPacketdp = newDatagramPacket(buf, buf.length, InetAddress.getLocalHost(), 9000);26 27              28 29               // 【3】发送30 31               socket.send(dp);32 33              34 35               // 【4】关闭36 37               socket.close();38 39          } catch (SocketExceptione) {40 41               e.printStackTrace();42 43          } catch (UnsupportedEncodingExceptione) {44 45               e.printStackTrace();46 47          } catch (UnknownHostExceptione) {48 49               e.printStackTrace();50 51          } catch (IOExceptione) {52 53               e.printStackTrace();54 55          }56 57      }

接收端

1 public static void main(String[] args) { 2  3          // 接收端:接收信息 4  5          System.out.println("启动接收端..."); 6  7          // 【1】创建一个DatagramSocket 8  9          DatagramSocketsocket = null;10 11          try {12 13               socket = newDatagramSocket(9000);14 15               // 【2】接收消息16 17               byte[] buf = newbyte[1024];18 19               DatagramPacketdp = newDatagramPacket(buf, buf.length);20 21               System.out.println("等待接收信息...");22 23               socket.receive(dp);24 25               System.out.println("接收完成...");26 27              28 29               // 处理接收的信息30 31               String msg = new String(buf, 0, dp.getLength(), "UTF-8");32 33               System.out.println(msg);34 35              36 37          } catch (SocketExceptione) {38 39               e.printStackTrace();40 41          } catch (IOExceptione) {42 43               e.printStackTrace();44 45          }46 47      }

需求:实现双向通信

发送端

1 public static void main(String[] args) { 2  3          4  5          // 发送端:主动发送信息 6  7          System.out.println("发送端开始发送信息..."); 8  9          Scanner sc = new Scanner(System.in);10 11          // 【1】创建socket并指定发送数据的端口12 13          DatagramSocketsocket = null;14 15          try {16 17               socket = newDatagramSocket(8000);18 19              20 21               for(;;) {22 23                    System.out.print("A说:");24 25                    String msg = sc.nextLine();26 27                    byte[] buf = msg.getBytes("UTF-8");28 29                    DatagramPacketdp = newDatagramPacket(buf, buf.length, InetAddress.getLocalHost(), 9000);30 31                   32 33                    // 【3】发送34 35                    socket.send(dp);36 37                   38 39                   40 41                    // 接收消息42 43                    byte[] revBuf = newbyte[1024];44 45                    DatagramPacketrevDp = newDatagramPacket(revBuf,revBuf.length);46 47                    socket.receive(revDp);48 49                    String revStr = newString(revBuf, 0, revDp.getLength(), "UTF-8");50 51                    System.out.println(dp.getAddress().getHostName()+":"+revStr);52 53               }54 55              56 57          } catch (SocketExceptione) {58 59               e.printStackTrace();60 61          } catch (UnsupportedEncodingExceptione) {62 63               e.printStackTrace();64 65          } catch (UnknownHostExceptione) {66 67               e.printStackTrace();68 69          } catch (IOExceptione) {70 71               e.printStackTrace();72 73          }finally {74 75               // 【4】关闭76 77               socket.close();78 79          }80 81      }

接收端

1     public static void main(String[] args) { 2  3          // 接收端:接收信息 4  5          System.out.println("启动接收端..."); 6  7          Scannersc = new Scanner(System.in); 8  9          // 【1】创建一个DatagramSocket10 11          DatagramSocketsocket = null;12 13         14 15          try {16 17               socket = newDatagramSocket(9000);18 19              20 21               for(;;) {22 23                    // 接收信息24 25                    byte[] buf = newbyte[1024];26 27                    DatagramPacketdp = newDatagramPacket(buf, buf.length);28 29                    socket.receive(dp);30 31                    String msg = new String(buf, 0, dp.getLength(), "UTF-8");32 33                    System.out.println(dp.getAddress().getHostName()+":"+msg);34 35                   36 37                    // 发送信息38 39                    System.out.println("B说:");40 41                    String sendMsg = sc.nextLine();42 43                    byte[] sendBuf = sendMsg.getBytes("UTF-8");44 45                    DatagramPacketsendDp = newDatagramPacket(sendBuf, 0, sendBuf.length, dp.getAddress(), dp.getPort());46 47                    socket.send(sendDp);48 49               }50 51              52 53          } catch (SocketExceptione) {54 55               e.printStackTrace();56 57          } catch (IOExceptione) {58 59               e.printStackTrace();60 61          }finally {62 63               socket.close();64 65          }66 67      }

 

转载于:https://www.cnblogs.com/qq2267711589/p/10846968.html

你可能感兴趣的文章
suse如何修改ssh端口为2222?
查看>>
详细理解“>/dev/null 2>&1”
查看>>
suse如何创建定时任务?
查看>>
suse搭建ftp服务器方法
查看>>
centos虚拟机设置共享文件夹并通过我的电脑访问[增加smbd端口修改]
查看>>
文件拷贝(IFileOperation::CopyItem)
查看>>
MapReduce的 Speculative Execution机制
查看>>
大数据学习之路------借助HDP SANDBOX开始学习
查看>>
Hadoop基础学习:基于Hortonworks HDP
查看>>
为什么linux安装程序 都要放到/usr/local目录下
查看>>
Hive安装前扫盲之Derby和Metastore
查看>>
永久修改PATH环境变量的几种办法
查看>>
大数据学习之HDP SANDBOX开始学习
查看>>
Hive Beeline使用
查看>>
Centos6安装图形界面(hdp不需要,hdp直接从github上下载数据即可)
查看>>
CentOS7 中把yum源更换成163源
查看>>
关于yum Error: Cannot retrieve repository metadata (repomd.xml) for repository:xxxxxx.
查看>>
2020-11-18
查看>>
Docker面试题(二)
查看>>
【NOI 2018】归程(Kruskal重构树)
查看>>