Java网络编程-你是GG还是MM?
第六阶段 网络编程
每一台计算机通过网络连接起来,达到了数据互动的效果,而网络编程所解决的问题就是如何让程序与程序之间实现数据的通讯与互动
在吗?你是GG还是MM?
(一) 网络模型概述
(1) 两大模型
网络模型一般是指:
- OSI(Open System Interconnection开放系统互连)参考模型
- TCP/IP参考模型
(2) 网络模型七层概述
物理层:主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。它的主要作用是传输比特流(就是由1、0转化为电流强弱来进行传输,到达目的地后在转化为1、0,也就是我们常说的数模转换与模数转换)。这一层的数据叫做比特。
数据链路层:主要将从物理层接收的数据进行MAC地址(网卡的地址)的封装与解封装。常把这一层的数据叫做帧。在这一层工作的设备是交换机,数据通过交换机来传输。
网络层:主要将从下层接收到的数据进行IP地址(例192.168.0.1)的封装与解封装。在这一层工作的设备是路由器,常把这一层的数据叫做数据包。
传输层:定义了一些传输数据的协议和端口号(WWW端口80等),如:TCP(传输控制协议,传输效率低,可靠性强,用于传输可靠性要求高,数据量大的数据),UDP(用户数据报协议,与TCP特性恰恰相反,用于传输可靠性要求不高,数据量小的数据,如QQ微信聊天数据就是通过这种方式传输的)。 主要是将从下层接收的数据进行分段和传输,到达目的地址后再进行重组。常常把这一层数据叫做段。
会话层:通过传输层(端口号:传输端口与接收端口)建立数据传输的通路。主要在你的系统之间发起会话或者接受会话请求(设备之间需要互相认识可以是IP也可以是MAC或者是主机名)
表示层:主要是进行对接收的数据进行解释、加密与解密、压缩与解压缩等(也就是把计算机能够识别的东西转换成人能够能识别的东西(如图片、声音等)。
应用层: 主要是一些终端的应用,比如说FTP(各种文件下载),WEB(IE浏览),QQ之类的(可以把它理解成我们在电脑屏幕上可以看到的东西.就是终端应用)。
(二) 网络编程三要素
(1) IP地址
A:IP地址概述:IP地址是网络中计算机的唯一标识**
我们应该或多或少都有见过IP地址的格式 xxx.xxx.xxx.xxx大致应该是类似这样的,但是计算机不是只能识别二进制的数据,但是很显然,我们的IP地址确实不是二进制的,这是什么原因呢?
我们先随便拿一个IP地址举个例子看看
IP:192.168.1.100
换算:11000000 10101000 00000001 01100100
但是如果我们日后需要用到这个IP地址的时候,记忆起来就比较麻烦,所以,为了方便表示IP地址,我们就把IP地址的每一个字节上的数据换算成十进制,然后用 ' . ' 分开来表示:"点分十进制"
B:IP地址的组成:网络号段+主机号段
A类:第一号段为网络号段+后三段的主机号段,一个网络号:256256256 = 16777216
B类:前二号段为网络号段+后二段的主机号段,一个网络号:256*256 = 65536
C类:前三号段为网络号段+后一段的主机号段,一个网络号:256
C:IP地址的分类
A类
1.0.0.1---127.255.255.254
(1)10.X.X.X是私有地址(私有地址就是在互联网上不使用,而被用在局域网络中的地址)
(2)127.X.X.X是保留地址,用做循环测试用的
B类
128.0.0.1---191.255.255.254
172.16.0.0---172.31.255.255是私有地址
169.254.X.X是保留地址
C类
192.0.0.1---223.255.255.254 192.168.X.X是私有地址
D类
224.0.0.1---239.255.255.254
E类
240.0.0.1---247.255.255.254
两个DOS命令
ipconfig 查看本机ip地址
ping 后面跟ip地址, 测试本机与指定的ip地址间的通信是否有问题
特殊IP地址
127.0.0.1 回环地址(表示本机)//也就是说,ping本机的IP地址相当于ping 127.0.0.1
x.x.x.255 广播地址
x.x.x.0 网络地址
InetAddress的成员方法
//根据主机名或者IP地址的字符串表示得到IP地址对象
public static InetAddress getByName(String host):
import java.net.InetAddress;
import java.net.UnknownHostException;
public class InetAddressDemo {
public static void main(String[] args) throws UnknownHostException {
InetAddress address = InetAddress.getByName("192.168.24.1");
//获取两个东西:主机名,IP地址
String name = address.getHostName();
String ip = address.getHostAddress();
System.out.println(name + "---" + ip);
}
}
//运行结果
LAPTOP-5T03DV1G---192.168.24.1
(2) 端口
物理端口 网卡口
逻辑端口 我们指的就是逻辑端口
每个网络程序都会至少有一个逻辑端口
用于标识进程的逻辑地址,不同进程的标识
有效端口:065535,其中01024系统使用或保留端口。
(3) 协议
TCP:传输控制协议,传输效率低,可靠性强,用于传输可靠性要求高,数据量大的数据
UDP:用户数据报协议,与TCP特性恰恰相反,用于传输可靠性要求不高,数据量小的数据,如QQ微信聊天数据就是通过这种方式传输的
简单总结:
TCP:建立数据通道,无限制,效率低,可靠
UDP:数据打包,有限制,不连接,效率高,不可靠
(三) 控制台简单聊天案例
(1) UDP版本 V1.0
import java.io.IOException;
import java.net.*;
/* UDP协议发送数据:
* A:创建发送端Socket对象
* B:创建数据,并把数据打包
* C:调用Socket对象的发送方法发送数据包
* D:释放资源
*/
public class SendDemo {
public static void main(String[] args) throws IOException {
//创建socket对象
DatagramSocket ds = new DatagramSocket();
//创建数据,并把数据打包
//DatagramPacket(byte[] buf, int length, InetAddress address, int port)
byte[] bys = "Hello,BWH!".getBytes();//把字符串转换成字符数组
int length = bys.length;
InetAddress address = InetAddress.getByName("192.168.24.1");
int port = 10086; //自拟
DatagramPacket dp = new DatagramPacket(bys, length, address, port);
//调用Socket对象的方法发送数据包
//public void send(DatagramPacket p)
ds.send(dp);
//释放资源
ds.close(); //底层依赖IO流,所以要释放资源
}
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
/*
* UDP协议接收数据:
* A:创建接收端Socket对象
* B:创建一个数据包(接收容器)
* C:调用Socket对象的接收方法接收数据
* D:解析数据包,并显示在控制台
* E:释放资源
*/
public class ReceiveDemo {
public static void main(String[] args) throws IOException {
// 创建接收端Socket对象
// DatagramSocket(int port)
DatagramSocket ds = new DatagramSocket(10086);
// 创建一个数据包(接收容器)
// DatagramPacket(byte[] buf, int length)
byte[] bys = new byte[1024];
int length = bys.length;
DatagramPacket dp = new DatagramPacket(bys, length);
// 调用Socket对象的接收方法接收数据
// public void receive(DatagramPacket p)
ds.receive(dp);
// 解析数据包,并显示在控制台
// 获取对方的ip
// public InetAddress getAddress()
InetAddress address = dp.getAddress();
String ip = address.getHostAddress();
// public byte[] getData():获取数据缓冲区
// public int getLength():获取数据的实际长度
byte[] bys2 = dp.getData();
int len = dp.getLength();
String s = new String(bys2, 0, len);
System.out.println(ip + ": " + s);
// 释放资源
ds.close();
}
}
(2) UDP 版本V2.0
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class SendDemo {
public static void main(String[] args) throws IOException {
//创建发送端的Socket对象
DatagramSocket ds = new DatagramSocket();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while ((line = br.readLine()) != null) {
if ("886".equals(line)) {
break;
}
//创建数据并打包
byte[] bys = line.getBytes();
DatagramPacket dp = new DatagramPacket(bys, bys.length, InetAddress.getByName("192.168.24.1"), 10086);
//发送数据
ds.send(dp);
}
//释放资源
ds.close();
}
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class ReceiveDemo {
public static void main(String[] args) throws IOException {
//创建接受端的Socket对象
DatagramSocket ds = new DatagramSocket(10086);
while (true) {
//创建一个包裹
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys, bys.length);
//接收数据
ds.receive(dp);
//解析数据
String ip = dp.getAddress().getHostAddress();
String s = new String(dp.getData(), 0, dp.getLength());
System.out.println(ip + ": " + s);
}
// 释放资源,但是接收端是服务器应该一直开启
//ds.close();
}
}
(3) UDP 版本V3.0
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class SendThread implements Runnable {
private DatagramSocket ds;
public SendThread(DatagramSocket ds) {
this.ds = ds;
}
@Override
public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while ((line = br.readLine()) != null) {
if ("886".equals(line)) {
break;
}
// 创建数据并打包
byte[] bys = line.getBytes();
DatagramPacket dp = new DatagramPacket(bys, bys.length, InetAddress.getByName("192.168.24.1"), 10086);
// 发送数据
ds.send(dp);
}
// 释放资源
ds.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class ReceiveThread implements Runnable {
private DatagramSocket ds;
public ReceiveThread(DatagramSocket ds) {
this.ds = ds;
}
@Override
public void run() {
try {
while (true) {
//创建一个包裹
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys, bys.length);
//接收数据
ds.receive(dp);
//解析数据
String ip = dp.getAddress().getHostAddress();
String s = new String(dp.getData(), 0, dp.getLength());
System.out.println("from " + ip + " data is : " + s);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.net.DatagramSocket;
import java.net.SocketException;
public class ChatRoom {
public static void main(String[] args) throws SocketException {
DatagramSocket dsSend = new DatagramSocket();
DatagramSocket dsReceive = new DatagramSocket(10086);
SendThread st = new SendThread(dsSend);
ReceiveThread rt = new ReceiveThread(dsReceive);
Thread t1 = new Thread(st);
Thread t2 = new Thread(rt);
t1.start();
t2.start();
}
}
(4) TCP版本
package cn.bwh_06_TCP2;
import java.io.*;
import java.net.Socket;
public class Clietn {
public static void main(String[] args) throws IOException {
Socket s = new Socket("192.168.24.1", 22222);
//键盘录入对象
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//把通道内的流包装一下
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line = null;
while ((line = br.readLine()) != null) {
if ("886".equals(line)) {
break;
}
bw.write(line);
bw.newLine();
bw.flush();
}
s.close();
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(22222);
Socket s = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
s.close();
}
}
(三) 其他功能
(1) 客户端键盘录入服务器写到文本文件
//封装通道内的数据
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//封装文本文件
BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt"));
(2) 客户端读取文本文件服务器控制台输出
//封装文本文件
BufferedReader br = new BufferedReader(new FileReader("Demo.java"));
//封装通道内的数据
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line = null;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
结尾:
如果内容中有什么不足,或者错误的地方,欢迎大家给我留言提出意见, 蟹蟹大家 !_
如果能帮到你的话,那就来关注我吧!(系列文章均会在公众号第一时间更新)
在这里的我们素不相识,却都在为了自己的梦而努力 ❤
一个坚持推送原创Java技术的公众号:理想二旬不止
Java网络编程-你是GG还是MM?的更多相关文章
- Java网络编程和NIO详解3:IO模型与Java网络编程模型
Java网络编程和NIO详解3:IO模型与Java网络编程模型 基本概念说明 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32 ...
- 20145205 《Java程序设计》实验报告五:Java网络编程及安全
20145205 <Java程序设计>实验报告五:Java网络编程及安全 实验要求 1.掌握Socket程序的编写: 2.掌握密码技术的使用: 3.客户端中输入明文,利用DES算法加密,D ...
- Java 网络编程学习总结
新手一枚,Java学习中,把自己学习网络编程的知识总结一下,梳理下知识,方便日后查阅,高手莫进. 本文的主要内容: [1] 网络编程认识 [2] TCP/IP编程 ...
- 20145212 实验五《Java网络编程》
20145212 实验五<Java网络编程> 一.实验内容 1.运行下载的TCP代码,结对进行,一人服务器,一人客户端: 2.利用加解密代码包,编译运行代码,一人加密,一人解密: 3.集成 ...
- 20145213《Java程序设计》实验五Java网络编程及安全
20145213<Java程序设计>实验五Java网络编程及安全 实验内容 1.掌握Socket程序的编写. 2.掌握密码技术的使用. 3.设计安全传输系统. 实验预期 1.客户端与服务器 ...
- 20145206《Java程序设计》实验五Java网络编程及安全
20145206<Java程序设计>实验五 Java网络编程及安全 实验内容 1.掌握Socket程序的编写: 2.掌握密码技术的使用: 3.设计安全传输系统. 实验步骤 我和201451 ...
- 20145337实验五Java网络编程及安全
20145337实验五Java网络编程及安全 实验内容 掌握Socket程序的编写 掌握密码技术的使用 设计安全传输系统 实验步骤 基于Java Socket实现安全传输 基于TCP实现客户端和服务器 ...
- java 网络编程复习(转)
好久没有看过Java网络编程了,现在刚好公司有机会接触,顺便的拾起以前的东西 参照原博客:http://www.cnblogs.com/linzheng/archive/2011/01/23/1942 ...
- JAVA课程实验报告 实验五 Java网络编程及安全
北京电子科技学院(BESTI) 实 验 报 告 课程:Java程序设计 班级:1353 姓名:韩玉琪 学号:20135317 成绩: 指导教师:娄嘉 ...
随机推荐
- 001_linux驱动之_驱动的加载和卸载
(一)驱动的安装: 1. 可以将驱动程序静态编译进内内核中 2. 也可以将它作为模块在使用的时候再加载 注:在配置内核时候,如果某个配置被设置为m,就表示它将会被编译成模块 (二)加载和卸载驱动使 ...
- 经过测试,feign只能通过@RequestBody传对象参数
通过feign调用,使用ModelAttribute 注解,参数没法传到对应的server
- PCIe - 那点点事
各位看官,这是我拷贝过来的,作为学习笔记(本人对图比较感兴趣,你说我懒也行,上图,这个看着舒服易懂): 1. Wire, lane, link 啥关系 注: PCIe 每条lane有1个双向通道(一个 ...
- MySQL数据分析(7)-SQL的两大学习框架
大家好,我是jacky,很高兴继续跟大家分享<MySQL数据分析实战>课程,前面的课程基本上我把MySQL的原理都做了一定的介绍,有好多朋友说学习MySQL是没有逻辑的,其实jacky是非 ...
- rtp发送 h265
自己写的select 做TCP服务端,把tcp数据按照RTSP协议解析,掉函数直接获取一帧音频,一帧视频这种,分包成RTP发送 用ffmpeg
- Linux下 Java 读取文件路径
一般文件路径在windows中用 \ 表示,但是在其他系统平台下比如linux中就不是 \ 所以java给我们提供了一个与平台无关的表示路径的常量 File.separator在windows中则表示 ...
- fluent中隐藏模型的开启【转载】
转载自:http://blog.sina.com.cn/s/blog_5fd791530100d5ic.html fluent中设置了一些隐藏模型,普通的用户界面是没有相关选项的,必须用相关命令开启. ...
- COM 基础 之 三大基础接口
摘自 http://blog.csdn.net/liang4/article/details/7530512 1 COM组件实际上是一个C++类,而接口都是纯虚类.组件从接口派生而来. 2 COM组件 ...
- DML:增、删、改表中数据
1. 添加数据 (1) 常规添加 INSERT INTO 表名(列名,列名,列名) VALUES(值,值,值); (2) 简化添加 INSERT INTO 表名 VALUES(值,值,值); 规则: ...
- 课下选做作业实现mypwd
2019-2020-1 20175227 <信息安全系统设计基础> 课下选做作业实现mypwd 要求 学习pwd命令 研究pwd实现需要的系统调用(man -k; grep),写出伪代码 ...