目录

1.基本概念

  • 定义:网络号+主机号。是四个32位的二进制数据,为方便记忆划分为四个8位。

    Demo:

连接特定的 DNS 后缀 . . . . . . . : hollysys.net

本地链接 IPv6 地址. . . . . . . . : fe80::a1e4:76bc:79be:9806%11

IPv4 地址 . . . . . . . . . . . . : 172.21.32.29

子网掩码 . . . . . . . . . . . . : 255.255.255.0

默认网关. . . . . . . . . . . . . : 172.21.32.254

这里的172.21.32三位都是网络号,最后的29是主机号。划分的依据是子网掩码中,255段都表示这是网络号段,最后的0是主机号段。

  • 要素:

    • IP

    • 端口

    • 协议

  • 分类:

    类别 | 内容 | 数量 | 使用范围

    -------|--------------------------------------------------|-----------------

    A类 | 一个网络号+三个主机号 | 2^24个 | 国家使用

    B类 | 两个个网络号+两个个主机号 | 2^12个 | 事业单位使用

    C类 | 三个网络号+一个主机号 | 2^8个 | 私人使用

2.常用函数

package per.liyue.code.net;

import java.net.InetAddress;
import java.net.UnknownHostException; public class GetIpAddress {
public static void main(String[] args) throws UnknownHostException{
//这个类没有构造,所以静态函数获取对象
InetAddress ip = InetAddress.getLocalHost();
//获取ip地址
System.out.println("我的Ip地址:" + ip.getHostAddress());
//获取机器名
System.out.println("我的Ip机器名:" + ip.getHostName()); //获取其他机器的IP信息-getByName既可以填出机器名,也可以填充IP
String otherIp = "172.21.32.20";
String nameIp = "AMS97-PC";
InetAddress getIP = InetAddress.getByName(otherIp);
System.out.println("目标机器的IP是:" + getIP.getHostName());
InetAddress getName = InetAddress.getByName(nameIp);
System.out.println("目标机器的IP是:" + getName.getHostAddress()); //可以用于获取某个域名下的IP
InetAddress[] a = InetAddress.getAllByName("www.hollysys.com");
for (InetAddress inetAddress : a) {
System.out.println("net:" + inetAddress.getHostAddress());
}
}
}

3.端口

  • 端口范围:0~65535,其中

    • 0~1023:系统端口:系统紧密绑定

    • 1024~49151:注册端口:系统松散绑定

    • 1024~65535:可用,如果出错则换另一个

4.协议

不同的协议对应不同的Scoket:

*

*

4.1UDP

4.1.1特点

  • 不需要建立连接
  • 每包大小64K
  • 速度快,非可靠(丢包)
  • 不区分客户端服务端,之区分发送端和接收端

4.1.2代码步骤

步骤

  • 发送端:

    • 建立服务DatagramSocket()

    • 创建数据包public DatagramPacket(byte buf[], int length,

                      InetAddress address, int port)    * 发送数据DatagramSocket.send()
    • 关闭资源

  • 接收端:

    • 建立服务绑定端口:public DatagramSocket(int port)

    • 创建数据包接收:public DatagramPacket(byte buf[], int length)

    • 用阻塞方法接收数据:DatagramSocket.receive()

    • 关闭资源

4.1.3UDPDemo

Demo:

package per.liyue.code.udptest;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
/*
* Udp发送类,用于发送数据
*/
public class UdpSender {
public static void main(String[] args) throws IOException {
//建立socket
DatagramSocket socketSend = new DatagramSocket(); //创建数据包
String sendConcent = "这是我发送的一包数据";
/*
* 这里使用DatagramPacket来存放发送数据,使用的构造是:
* public DatagramPacket(byte buf[], //缓冲数组存放发送数据
* int length, //要用缓冲数组的长度
* InetAddress address,//目标IP地址
* int port //目标端口
* )
*
* */
DatagramPacket packetSend = new DatagramPacket(sendConcent.getBytes(), sendConcent.getBytes().length, InetAddress.getLocalHost(), 10001); //发送数据
socketSend.send(packetSend);
socketSend.close();
System.out.println("数据已经发送,时间:" + new SimpleDateFormat("yyyy-MM-DD HH-mm-ss").format(new Date()));
}
}
package per.liyue.code.udptest;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
* Udp接收数据类,用于接收数据
*/
public class UdpReceive {
public static void main(String[] args) throws IOException {
//建立socket
DatagramSocket socketReceive = new DatagramSocket(10001); System.out.println("接收端开启监听..."); //数据包接收
byte[] bufRecive = new byte[1024];
/*
* 用DatagramPacket来接收数组,这里要用构造:
* public DatagramPacket(byte buf[], //缓冲数组来接收,数据实际存放于数组中
* int length) //缓冲数组长度
*/
DatagramPacket packetReceive = new DatagramPacket(bufRecive, bufRecive.length); //这个方法是阻塞的:This method blocks until a datagram is received。收到数据才执行
socketReceive.receive(packetReceive);
socketSend.close();
//要注意的是
System.out.println("接收到数据:" + new String(bufRecive, 0, packetReceive.getLength()));
System.out.println("接收时间:" + new SimpleDateFormat("yyyy-MM-DD HH-mm-ss").format(new Date())); }
}

4.1.4通信格式

一般的通信中,数据内容有规定的格式,否则当垃圾数据处理,例如飞秋的为:

version:time:sender:ip:flag:concnet

  • 这里的版本号强制使用1.0
  • 时间使用系统时间
  • 发送人随意
  • ip是给对方显示地址
  • flag强制为32
  • concent是真正的内容
package per.liyue.code.udptest;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class UdpSendFeiQ {
public static void main(String[] args) throws IOException {
DatagramSocket send = new DatagramSocket(); String concent = getconcent("飞啊飞");
System.out.println("发送内容: " + concent);
DatagramPacket packet = new DatagramPacket(concent.getBytes(), concent.getBytes().length,
InetAddress.getByName("172.21.32.20"), 2425);
send.send(packet);
send.close();
}
/*
* 飞秋的数据格式:version:time:sender:ip:flag:concnet
* 1.0 32
*/ public static String getconcent(String concent) {
StringBuilder builder = new StringBuilder();
builder.append("1.0:");
builder.append(System.currentTimeMillis() + ":");
builder.append("172.21.32.30:");
builder.append("超人:");
builder.append("32:");
builder.append(concent);
return builder.toString();
}
}

广播地址:在UDP中将主机号修改为255就是网络广播地址,会群发。例如飞秋的地址为:

172.21.32.255

4.1.5 群发Demo:

package per.liyue.code.udptest;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.Runnable;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException; public class ChatSender implements Runnable {
@Override
public void run() {
try {
//
DatagramSocket send = new DatagramSocket(); //
BufferedReader read = new BufferedReader(
new InputStreamReader(System.in));
String line = null;
DatagramPacket packet = null;
while((line = read.readLine()) != null){
packet = new DatagramPacket(line.getBytes(), line.getBytes().length,
InetAddress.getLocalHost(), 10001);
send.send(packet);
}
send.close();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}
package per.liyue.code.udptest;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class ChatReceive implements Runnable {
@Override
public void run() {
try {
// TODO Auto-generated method stub
DatagramSocket socket = new DatagramSocket(10001);
byte[] concent = new byte[1024];
DatagramPacket packet = new DatagramPacket(concent, concent.length); boolean flag = true;
while (flag) {
socket.receive(packet);
System.out.println(
packet.getAddress().getHostName() + "说:" +
new String(concent, 0, concent.length));
}
socket.close(); } catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package per.liyue.code.udptest;
public class ChatMain {
public static void main(String[] args) {
// TODO Auto-generated method stub
ChatReceive receive = new ChatReceive();
ChatSender send = new ChatSender();
new Thread(receive).start();
new Thread(send).start();
}
}

4.1.6丢失数据的情况

  • 带宽不够
  • cpu处理能力不足

目录

目录

4.2TCP

  • 面向连接:建立连接
  • 大数据,数据传输时候没有大小限制
  • 效率相对低:三次握手机制,可靠
  • 区分客户端服务的

4.2.1三次握手机制

发送数据之前要检查通路是否正常,所以是可靠连接。

4.2.2通信范例

  • 客户端:发送命令方-》Socket类
  • 服务端:接收命令方-》ServerSocket类

4.2.2.1单次通信

Demo:

单次建立连接通信:

package per.liyue.code.tcptest;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
//建立socket链接,指定IP和端口号
Socket socket = new Socket(InetAddress.getLocalHost(), 10001);
//获取到输出流
OutputStream out = socket.getOutputStream(); String conent = "我是客户端,向服务端发送数据了!";
//这里用输出流的写方法发送
out.write(conent.getBytes());
//关闭资源,输出流是从Socket中获取,所以关闭Socket就可以了
socket.close();
}
}
package per.liyue.code.tcptest;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) throws IOException {
//建立服务端监听端口
ServerSocket sSocket = new ServerSocket(10001); //accept方法本身也是阻塞的方法
Socket socket = sSocket.accept();
//因为ServerSocket本身没有流对象的获取,所以要从Socket中获取,客户端发送的时候已经将流发送 InputStream in = socket.getInputStream(); byte[] b = new byte[1024];
int length = in.read(b);
//打印接收内容
System.out.println("服务器接收到的数据:" + new String(b, 0, length));
//关闭资源,输入流和Socket都是通过ServerSocket获取,所以关闭一个即可
sSocket.close();
}
}

注意:为什么不对ServerSocket提供getInputStream和getOutputStream,因为如果ServerSocket本身有提供,在多客户端连接时候,服务端回复的话一个输入输出不能辨别出回复到哪个客户端。所以设计了Socket提供。

4.2.2.2持久化通信

Demo:

package per.liyue.code.tcptest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import com.sun.imageio.plugins.common.InputStreamAdapter;
/*
* TCp实现客户端和服务器互相通信
*/
public class ClientChat {
public static void main(String[] args) {
try {
System.out.println("客户端已经打开,准备发送..."); //创建
Socket socket = new Socket(InetAddress.getLocalHost(), 10001); OutputStream out = socket.getOutputStream();
//将字符流转换为字节流方便传输
OutputStreamWriter send = new OutputStreamWriter(out); //获取键盘输入流,将输入的字节流转化为字符流
InputStreamReader in = new InputStreamReader(System.in);
BufferedReader bufRead = new BufferedReader(in); String line = null;
while((line=bufRead.readLine()) != null){
/*
* 将输入的内容发送
* 注意:因为接收的时候也以readLine来接收,这个方法以回车换行来判断,
* 但是这里的获取输入并不会增加换行回车,所以得手动增加
*/
send.write(line + "\r\n");
//这里不能忘记刷新,否则内容只存在于缓存数组中
send.flush()
}
socket.close(); } catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}
package per.liyue.code.tcptest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerChat {
public static void main(String[] args) { try {
System.out.println("服务端已经打开,等待接收..."); //创建ServerSocket
ServerSocket sSocket = new ServerSocket(10001);
//获取Socket对象
Socket socket = sSocket.accept();
//获取输入流
InputStream in = socket.getInputStream();
InputStreamReader inRead = new InputStreamReader(in); //将收到的字节流转换为字符流方便输出
BufferedReader read = new BufferedReader(inRead); String line = null;
while ((line = read.readLine()) != null) {
System.out.println("服务端收到:" + line);
}
sSocket.close(); } catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}

4.2.2.3持久化相互通信

Demo:

package per.liyue.code.tcptest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import com.sun.imageio.plugins.common.InputStreamAdapter;
/*
* TCp实现客户端和服务器互相通信
*/
public class ClientChat {
public static void main(String[] args) {
try {
System.out.println("客户端已经打开,准备发送...");
/*
* 输出流准备
*/
//创建
Socket socket = new Socket(InetAddress.getLocalHost(), 10001); OutputStream out = socket.getOutputStream();
//将字符流转换为字节流方便传输
OutputStreamWriter send = new OutputStreamWriter(out); //获取键盘输入流,将输入的字节流转化为字符流
InputStreamReader in = new InputStreamReader(System.in);
BufferedReader bufRead = new BufferedReader(in); String line = null; /*
* 输入准备
*/
//获取输入流
//获取输入内容
BufferedReader readFormServer = new BufferedReader(
new InputStreamReader(socket.getInputStream())
); while((line=bufRead.readLine()) != null){
/*
* 将输入的内容发送
* 注意:因为接收的时候也以readLine来接收,这个方法以回车换行来判断,
* 但是这里的获取输入并不会增加换行回车,所以得手动增加
*/
send.write(line + "\r\n");
//这里不能忘记刷新,否则内容只存在于缓存数组中
send.flush(); //收到服务端
String lineRead = readFormServer.readLine();
System.out.println("客户端收到:" + lineRead);
}
socket.close(); } catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}
package per.liyue.code.tcptest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerChat {
public static void main(String[] args) { try {
System.out.println("服务端已经打开,等待接收..."); /*
* 获取输入准备
*/
//创建ServerSocket
ServerSocket sSocket = new ServerSocket(10001);
//获取Socket对象
Socket socket = sSocket.accept();
//获取输入流
InputStream in = socket.getInputStream();
InputStreamReader inRead = new InputStreamReader(in); //将收到的字节流转换为字符流方便输出
BufferedReader read = new BufferedReader(inRead); String line = null;
/*
* 输出准备
*/
//获取输出流
OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream());
//获取准备输出的数据
BufferedReader write = new BufferedReader(new InputStreamReader(System.in)); while ((line = read.readLine()) != null) {
System.out.println("服务端收到:" + line); String lineWrite = write.readLine();
out.write("服务端说:" + lineWrite + "\r\n");
out.flush();
}
sSocket.close(); } catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}

23.网络.md的更多相关文章

  1. day 23 网络编程

    C/S架构 Client与Server B/S架构 Browser与Server windows上查看端口占用情况 netstat -a OSI七层模型: 其他略...

  2. docker网络实践

    docker网络.md #docker 网络模式 环境 centos7.4 , Docker version 17.12.0-ce docker自带网络类型 bridge,host,none,cont ...

  3. AJAX请求真的不安全么?谈谈Web安全与AJAX的关系。

    开篇三问 AJAX请求真的不安全么? AJAX请求哪里不安全? 怎么样让AJAX请求更安全? 前言 本文包含的内容较多,包括AJAX,CORS,XSS,CSRF等内容,要完整的看完并理解需要付出一定的 ...

  4. 二进制方式安装Kubernetes 1.14.2高可用详细步骤

    00.组件版本和配置策略 组件版本 Kubernetes 1.14.2 Docker 18.09.6-ce Etcd 3.3.13 Flanneld 0.11.0 插件: Coredns Dashbo ...

  5. Linux运维常用命令总结

    1.删除0字节文件 find -type f -size 0 -exec rm -rf {} \;   2.查看进程 按内存从大到小排列 PS -e   -o "%C   : %p : %z ...

  6. iOS开发小技巧

    1. 解析详情页(是webView)遇到的3个问题: 1.图片太大,超出屏幕范围 2.怎么在webView上面添加一行文字 3.文字太小 1.解决方法 webView.scalesPageToFit ...

  7. 精选37条强大的常用linux shell命令组合

    任务                             命令组合 1 删除0字节文件 find . -type f -size 0 -exec rm -rf {} \;find . type f ...

  8. Oracle—用户管理的完全恢复(一)

    一.分类 可以分为在非归档模式下和归档模式下的完全恢复,完全恢复主要是针对归档模式下的,在非归档模式下很难做到完全恢复,除非是在做恢复时,联机重做日志还没有被重写. 二.非归档的有关性质 1.在非归档 ...

  9. linux运维常用命令集

    1.删除0字节文件 find -type f -size 0 -exec rm -rf {} \;   2.查看进程 按内存从大到小排列 PS -e   -o "%C   : %p : %z ...

随机推荐

  1. Delphi 常用语句

    1.屏蔽Float浮点数出错: Set8087CW(Longword($133f)); 2.Idhttp参数设置: FIdhttp                  := TIdHTTP.Create ...

  2. 动态添加布局、动态添加View、LinearLayout动态添加View;

    LinearLayout提供了几个方法,用作动态添加View特别好用: 可以添加View.删除View.删除指定位置View.删除全部View: 看代码: public class MainActiv ...

  3. Android MVP案例;

    就一个十分简单的获取列表数据并展示的Demo:分别使用MVC和MVP实现: 先来一个假的数据源: //假设这就是数据源 public class UserBean { public static Li ...

  4. Android最新版支付宝支付集成

    上次集成支付宝支付已经很久了,今天写东西用到了支付宝支付,就大致写一下流程: 去蚂蚁金服下载最新版的Android&IOS端SDK 全部文档 -- 资源下载 -- App支付客户端 下载后解压 ...

  5. Solr——Windows下部署Solr6.6.0至Tomcat8.5.28(二)

    1,core理解 如果把solr理解为个数据库的话,那么core可以理解为数据库中的一张表,其实就是数据集合 在写本片文章之前看到网上很多教程都说需要找到solr.xml来配置core的信息,特此说明 ...

  6. SpringBoot入门 (十) 发送邮件

    本文记录学习在SpringBoot中发送邮件. 一 邮件发送过程 发送邮件是一个我们在项目中经常会用到的功能,如在用户注册时发送验证码,账户激活等都会用到.完整的一个邮件发送过程主要包含以下几个步骤: ...

  7. CouldnotcreatetheJavaVirtualMachine/1709

    Section A: symptom --------------------   SWPM1024 S/4hana 1709 安装过程中遇到error, 错误提示错误信息在/tmp/sapinst_ ...

  8. 10.Ubuntu操作系统及python2.7、3.5 exe

    Ubuntu操作系统 链接:https://pan.baidu.com/s/1cu_eYN1GnW5EwVYrXMJbEg 密码:advq python-3.5.3_32位 链接:https://pa ...

  9. EA Data Modeling 显示别名设置

    1.设置 2.效果 

  10. django之def get_response(self, request):

    class BaseHandler(object)方法get_response,控制着处理请求的流程,调用中间件,返回请求. def get_response(self, request): &quo ...