目录

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. 有关Set集合的一个小问题

    先看两段代码: Demo1: Set<Short>s=new HashSet<>(); for(Short i=0;i<100;i++){ s.add(i); s.rem ...

  2. Centos配置iptables开放ftp服务

    安装完vsftpd后,默认情况下,CentOS的防火墙是不开放ftp服务的,需要添加模块和开放21端口才能提供ftp访问.1.添加ip_conntrack_ftp 模块[root@hexuweb101 ...

  3. mysql的DATE_FORMAT参数格式

    mysql有个字段是DATETIME类型,要实现可以按月统计,该怎么写sql语句?select month(f1) from tt group by month(f1)or select DATE_F ...

  4. .Net 大型分布式基础服务架构横向演变概述(转)

    一. 业务背景 构建具备高可用,高扩展性,高性能,能承载高并发,大流量的分布式电子商务平台,支持用户,订单,采购,物流,配送,财务等多个项目的协作,便于后续运营报表,分析,便于运维及监控. 二. 基础 ...

  5. Linux最大线程数限制及当前线程数查询

    常用配置 echo > /proc/sys/kernel/pid_max a) 当前环境生效 ulimit -d unlimited ulimit -m unlimited ulimit -s ...

  6. python import问题

    python中包:一个文件夹中必须要有__init__.py文件,才能被识别为 包,才能被其他模块引入python中 模块的查找顺序是:内存中已经加载的模块->内置模块->sys.path ...

  7. QSetting 说明和简单使用

    今天看到服务端代码有一个QSetting.一开始以为是STL模板中的Set(弄到QT中改了个名字而已).仔细一看吓一跳,不是STL模板.是qt特有的一个类. 用来保存或读取一些配置信息用的.看了后,感 ...

  8. java 多线程(生产者消费者)

    转 https://www.oschina.net/code/snippet_111708_25438 这个问题挺经典,我这个解法的本质在于将问题抽象为生产者消费者模型,但是是一个特殊的生产者消费者模 ...

  9. 什么是事务、事务特性、事务隔离级别、spring事务传播特性

    1.什么是事务: 事务是程序中一系列严密的操作,所有操作执行必须成功完成,否则在每个操作所做的更改将会被撤销,这也是事务的原子性(要么成功,要么失败). 2.事务特性: 事务特性分为四个:原子性(At ...

  10. 输出单个文件中的前 N 个最常出现的英语单词,并将结果输入到文本文件中。程序设计思路。

    将文件内容读取后存入StringBuffer中. 利用函数将段落分割成字符串,按(“,”,“.”,“!”,“空格”,“回车”)分割,然后存入数组中. 遍历数组,并统计每个单词及其出现的次数. 要求出文 ...