网络模型一般是指:
A:IP地址概述:IP地址是网络中计算机的唯一标识
我们应该或多或少都有见过IP地址的格式 http://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 网络地址
每个网络程序都会至少有一个逻辑端口
用于标识进程的逻辑地址,不同进程的标识
0 ~ 1024
为被系统使用或保留的端口号,0 ~ 65535
为有效的端口号,也就是说我们要对一些程序定义端口号的时候,要选择1024 ~ 65535范围内的整数数字。
比如,以前学过的MySQL的端口号是3306,SQLServer的端口号是1433,查了一下Oracle的端口号是1521。
一定要把这些数据库对应的端口号,藏在深深的脑海里,以后在连接数据库的时候,会使用到端口号。
第一种:TCP协议 英文名:Transmission Control Protocol 中文名:传输控制协议 协议说明:TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议。
第二种:UDP协议 英文名:User Datagram Protocol 中文名:数据报协议 协议说明:UDP是一种面向无连接的传输层通信协议。
SendDemo
package cn.itcast.network.demo.udp_v1;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/*
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("localhost");//本地ip地址
int port=10086;//自拟
DatagramPacket dp=new DatagramPacket(bys,length, address, port);
//调用socket对象的方法发送数据包
ds.send(dp);
//释放资源
ds.close();//底层依赖IO流,所以要释放资源
}
}
ReceiveDemo
package cn.itcast.network.demo.udp_v1;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/*
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();
}
}
先启动ReceiveDemo,再启动SendDemo,查看结果
UDP 版本V2.0可在控制台输入内容
SendDemo
package cn.itcast.network.demo.udp_v2;
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("localhost"),10086);
//发送数据
ds.send(dp);
}
//释放资源
ds.close();
}
}
ReceiveDemo
package cn.itcast.network.demo.udp_v2;
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();
}
}
发送端依次输入消息发送,当输入886停止发送消息
UDP 版本V3.0可不用分别开启发送方和接收方,直接运行聊天室 ChatRoom
即可
ChatRoom
package cn.itcast.network.demo.udp_v3;
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();
}
}
SendThread
package cn.itcast.network.demo.udp_v3;
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("localhost"), 10086);
// 发送数据
ds.send(dp);
}
// 释放资源
ds.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
ReceiveThread
package cn.itcast.network.demo.udp_v3;
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();
}
}
}
测试结果
TCP是基于字节流的传输层通信协议,所以TCP编程是基于IO流编程。
对于客户端,我们需要使用Socket类来创建对象。对于服务器端,我们需要使用ServerSocket来创建对象,通过对象调用accept()方法来进行监听是否有客户端访问。
客户端与服务器端图解:
代码实现:
Client 客户端
package cn.itcast.network.demo.tcp;
import java.io.*;
import java.net.Socket;
public class Client {
public static void main(String[] args) throws IOException {
Socket s=new Socket("localhost",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();
}
}
Server 服务端
package cn.itcast.network.demo.tcp;
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();
}
}
测试结果
The End!